Span<T>.Enumerator Struktur
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
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
- 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
ResetMethode, 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. |