Span<T>.Enumerator Struktur

Definition

Stellt einen Enumerator für die Elemente eines .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

Typparameter

T
Vererbung
Span<T>.Enumerator
Implementiert

Hinweise

C# foreach der C#-Sprache und der For Each... Als NächstesKonstrukt in Visual Basic die Komplexität von Enumeratoren ausblendet. Anstatt den Enumerator direkt zu bearbeiten, verwenden foreach oder For Each...Next wird empfohlen.

Zunächst wird der Enumerator vor dem ersten Element in der Span<T>Enumerator positioniert. An dieser Position Current ist nicht definiert. Sie müssen aufrufen MoveNext , um den Enumerator zum ersten Element im Span<T> Vorlesen des Werts Currentzu wechseln.

Current gibt denselben Wert zurück, bis MoveNext er aufgerufen wird. MoveNextwird Current auf das nächste Element in der .Span<T>

Wenn MoveNext das Ende des Span<T>MoveNext , gibt .false Wenn sich der Enumerator in diesem Zustand befindet, werden nachfolgende Aufrufe MoveNext zurückgegeben false und Current sind nicht definiert. Sie können das erste Element nicht erneut Span<T> festlegenCurrent. Stattdessen müssen Sie eine neue Enumerationsinstanz erstellen.

Der Enumerator hat keinen exklusiven Zugriff auf die Span<T>. Darüber hinaus können die zugrunde liegenden Daten, auf denen die Spanne basiert, ebenfalls geändert werden. Daher ist das Aufzählen über einen Span-Bereich grundsätzlich keine threadsichere Prozedur. Um die Threadsicherheit während der Enumeration zu gewährleisten, müssen Sie ihre eigene Synchronisierung implementieren. Der folgende Code hat z. B. eine Racebedingung. Es wird nicht sichergestellt, dass die Spanne vor der Ausführung der ClearContents Methode aufgezählt wird. Daher wird das zugrunde liegende Array während der Aufzählung der Spanne gelöscht:

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

Wenn Sie den Zugriff auf das Array synchronisieren, bevor Sie die Spanne aufzählen, da die überarbeitete Version der EnumerateSpan Methode im folgenden Beispiel ausgeführt wird, ändert die Methode die ClearContents zugrunde liegenden Span-Daten während der Enumeration nicht. Beachten Sie, dass das Beispiel das zugrunde liegende Array sperrt, auf dem die Spanne basiert.

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

Im Gegensatz zu einigen anderen Enumerationsstrukturen in .NET, Span<T>.Enumerator:

  • Implementiert weder die Schnittstelle noch die IEnumeratorIEnumerator<T> Schnittstelle. Dies liegt daran, dass Span<T>.Enumerator es sich um eine Refstruktur handelt.

  • Enthält keine Reset Methode, die den Enumerator vor dem ersten Element in der Spanne auf seine Anfangsposition festlegen kann. (Die IEnumerator.Reset() Methode muss als Teil der Schnittstelle implementiert werden, aber die meisten Implementierungsmodule lösen entweder eine Ausnahme aus oder stellen keine Implementierung bereit.)

Eigenschaften

Name Beschreibung
Current

Ruft einen Verweis auf das Element an der aktuellen Position des Enumerators ab.

Methoden

Name Beschreibung
MoveNext()

Wechselt den Enumerator zum nächsten Element der .Span<T>

Explizite Schnittstellenimplementierungen

Name Beschreibung
IDisposable.Dispose()

Führt anwendungsdefinierte Aufgaben aus, die mit dem Freigeben, Freigeben oder Zurücksetzen nicht verwalteter Ressourcen verknüpft sind.

IEnumerator.Current

Ruft das Element in der Auflistung an der aktuellen Position des Enumerators ab.

IEnumerator.Reset()

Legt den Enumerator auf seine Anfangsposition fest, die sich vor dem ersten Element in der Auflistung befindet.

IEnumerator<T>.Current

Ruft das Element in der Auflistung an der aktuellen Position des Enumerators ab.

Gilt für: