Span<T>.Enumerator 구조체
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
의 요소 Span<T>에 대한 열거자를 제공합니다.
public: value class Span<T>::Enumerator : System::Collections::Generic::IEnumerator<T>
public: value class Span<T>::Enumerator
public ref struct Span<T>.Enumerator : System.Collections.Generic.IEnumerator<T>
public ref struct Span<T>.Enumerator
type Span<'T>.Enumerator = struct
interface IEnumerator<'T>
interface IEnumerator
interface IDisposable
type Span<'T>.Enumerator = struct
Public Structure Span(Of T).Enumerator
Implements IEnumerator(Of T)
Public Structure Span(Of T).Enumerator
형식 매개 변수
- T
- 상속
- 구현
설명
C# 언어의 C# foreach 및 For Each... 다음 Visual Basic 구문은 열거자의 복잡성을 숨깁니다. 열거자를 직접 조작하는 대신 사용 foreach 하거나 For Each...Next 사용하는 것이 좋습니다.
처음에는 열거자가 .의 첫 번째 요소 앞에 배치됩니다 Span<T>. 이 위치에서 Current 정의되지 않습니다. 값을 읽기 Current전에 열거자를 첫 번째 항목으로 Span<T> 이동하도록 호출 MoveNext 해야 합니다.
Current 는 호출될 때까지 MoveNext 동일한 값을 반환합니다. MoveNext에서 다음 항목으로 Span<T>설정합니다Current.
의 끝을 Span<T>MoveNext 통과하면 MoveNext .를 반환합니다false. 열거자가 이 상태에 있으면 후속 호출 MoveNext 도 반환 false 되고 Current 정의되지 않습니다. 다시 첫 번째 항목 Span<T> 으로 설정할 Current 수 없습니다. 대신 새 열거자 인스턴스를 만들어야 합니다.
열거자에는 .에 대한 단독 액세스 권한이 Span<T>없습니다. 또한 범위의 기반이 되는 기본 데이터도 수정할 수 있습니다. 따라서 범위를 열거하는 것은 본질적으로 스레드로부터 안전한 프로시저가 아닙니다. 열거 중 스레드 안전을 보장하려면 사용자 고유의 동기화를 구현해야 합니다. 예를 들어 다음 코드에는 경합 상태가 있습니다. 메서드가 실행되기 전에 ClearContents 범위가 열거되지는 않습니다. 따라서 범위를 열거하는 동안 기본 배열이 지워집니다.
using System;
using System.Threading.Tasks;
class Program
{
private static readonly byte[] _array = new byte[5];
static void Main()
{
new Random(42).NextBytes(_array);
Span<byte> span = _array;
Task.Run( () => ClearContents() );
EnumerateSpan(span);
}
public static void ClearContents()
{
Task.Delay(20).Wait();
lock (_array)
{
Array.Clear(_array, 0, _array.Length);
}
}
public static void EnumerateSpan(Span<byte> span)
{
foreach (byte element in span)
{
Console.WriteLine(element);
Task.Delay(10).Wait();
}
}
}
// The example displays output like the following:
// 62
// 23
// 186
// 0
// 0
module Program
open System
open System.Threading.Tasks
let array = Array.zeroCreate<byte> 5
let clearContents () =
Task.Delay(20).Wait()
lock array (fun () ->
Array.Clear(array, 0, array.Length) )
let enumerateSpan (span: Span<byte>) =
for element in span do
printfn $"{element}"
Task.Delay(10).Wait()
[<EntryPoint>]
let main _ =
Random(42).NextBytes array
printfn "%A" array
let span: Span<byte> = array
Task.Run clearContents |> ignore
enumerateSpan span
0
// The example displays output like the following:
// 62
// 23
// 186
// 0
// 0
다음 예제 ClearContents 에서 수정된 버전의 EnumerateSpan 메서드처럼 범위를 열거하기 전에 배열에 대한 액세스를 동기화하는 경우 메서드는 열거 중에 기본 범위 데이터를 수정하지 않습니다. 이 예제에서는 범위의 기반이 되는 기본 배열을 잠깁니다.
public static void EnumerateSpan(Span<byte> span)
{
lock (_array)
{
foreach (byte element in span)
{
Console.WriteLine(element);
Task.Delay(10).Wait();
}
}
}
// The example displays the following output:
// 62
// 23
// 186
// 150
// 174
let enumerateSpan (span: Span<byte>) =
// Spans cannot be accessed in closures including in the F# lock function.
// Monitor.Enter and Monitor.Exit are used here directly.
Monitor.Enter array
try
for element in span do
printfn $"{element}"
Task.Delay(10).Wait()
finally
Monitor.Exit array
// The example displays the following output:
// 62
// 23
// 186
// 150
// 174
.NET 다른 열거자 구조와 달리 Span<T>.Enumerator:
또는 IEnumerator<T> 인터페이스를 IEnumerator 구현하지 않습니다. 이는 ref 구조체이기 때문 Span<T>.Enumerator 입니다.
열거자를 범위의 첫 번째 요소 앞의 초기 위치로 설정할 수 있는 메서드를 포함하지
Reset않습니다. (메서드는 IEnumerator.Reset() 인터페이스의 일부로 구현되어야 하지만 대부분의 구현자는 예외를 throw하거나 구현을 제공하지 않습니다.)
속성
| Name | Description |
|---|---|
| Current |
열거자의 현재 위치에 있는 항목에 대한 참조를 가져옵니다. |
메서드
| Name | Description |
|---|---|
| MoveNext() |
열거자를 다음 항목 Span<T>으로 이동합니다. |
명시적 인터페이스 구현
| Name | Description |
|---|---|
| IDisposable.Dispose() |
관리되지 않는 리소스의 해제, 해제 또는 재설정과 관련된 애플리케이션 정의 작업을 수행합니다. |
| IEnumerator.Current |
열거자의 현재 위치에 있는 컬렉션의 요소를 가져옵니다. |
| IEnumerator.Reset() |
열거자를 컬렉션의 첫 번째 요소 앞에 있는 초기 위치로 설정합니다. |
| IEnumerator<T>.Current |
열거자의 현재 위치에 있는 컬렉션의 요소를 가져옵니다. |