Span<T>.Enumerator 구조체
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
Span<T>의 요소에 대한 열거자를 제공합니다.
public: value class Span<T>::Enumerator
public ref struct Span<T>.Enumerator
type Span<'T>.Enumerator = struct
Public Structure Span(Of T).Enumerator
형식 매개 변수
- T
- 상속
설명
C# 언어 및 For Each의 C# foreach... Visual Basic의 다음 구문은 열거자의 복잡성을 숨깁니다. 열거자를 직접 조작하는 대신 사용 foreach
하거나 For Each...Next
사용하는 것이 좋습니다.
처음에는 열거자가 의 첫 번째 요소 Span<T>앞에 배치됩니다. 이 위치에서 Current는 정의되지 않습니다. 값을 Current읽기 전에 열거자를 첫 번째 항목으로 Span<T> 이동하려면 호출 MoveNext 해야 합니다.
Current 는 호출될 때까지 MoveNext 동일한 값을 반환합니다. MoveNext에서 다음 항목으로 Span<T>설정합니다Current.
의 끝을 통과하면 MoveNext .를 Span<T>MoveNext 반환합니다false
. 열거자가 이 상태에 있으면 후속 호출도 반환 false
되고 MoveNext 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하거나 구현을 제공하지 않습니다.)
속성
Current |
열거자의 현재 위치에 있는 항목에 대한 참조를 가져옵니다. |
메서드
MoveNext() |
열거자를 Span<T>의 다음 항목으로 이동합니다. |