Span<T>.Enumerator Struct
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Fornisce un enumeratore per gli elementi di un oggetto 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
Parametri di tipo
- T
- Ereditarietà
- Implementazioni
Commenti
C# foreach del linguaggio C# e For Each... Successivamente costrutto in Visual Basic nasconde la complessità degli enumeratori. Anziché modificare direttamente l'enumeratore, è consigliabile usare foreach o For Each...Next .
Inizialmente, l'enumeratore viene posizionato prima del primo elemento dell'oggetto Span<T>. In questa posizione, Current non è definito. È necessario chiamare per far avanzare MoveNext l'enumeratore al primo elemento di Span<T> prima di leggere il valore di Current.
Current restituisce lo stesso valore fino a quando MoveNext non viene chiamato . MoveNext imposta Current sull'elemento successivo nell'oggetto Span<T>.
Se MoveNext passa la fine di Span<T>, MoveNext restituisce false. Quando l'enumeratore è in questo stato, anche le chiamate successive a MoveNext restituiscono false e Current non sono predefinite. Non è possibile impostare Current nuovamente il primo elemento. È invece necessario creare una nuova istanza dell'enumeratore Span<T> .
L'enumeratore non ha accesso esclusivo all'oggetto Span<T>. Inoltre, è possibile modificare anche i dati sottostanti su cui si basa l'intervallo. Pertanto, l'enumerazione tramite un intervallo non è intrinsecamente una procedura thread-safe. Per garantire la thread safety durante l'enumerazione, è necessario implementare la sincronizzazione personalizzata. Ad esempio, il codice seguente ha una race condition. Non garantisce che l'intervallo venga enumerato prima dell'esecuzione del ClearContents metodo. Di conseguenza, la matrice sottostante viene cancellata durante l'enumerazione dell'intervallo:
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
Se si sincronizza l'accesso alla matrice prima di enumerare l'intervallo, come la versione modificata del EnumerateSpan metodo nell'esempio seguente, il ClearContents metodo non modifica i dati dell'intervallo sottostante durante l'enumerazione. Si noti che l'esempio blocca la matrice sottostante su cui si basa l'intervallo.
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
A differenza di altre strutture dell'enumeratore in .NET, il Span<T>.Enumerator:
Non implementa l'interfaccia IEnumerator o IEnumerator<T> . Questo perché Span<T>.Enumerator è uno struct di riferimento.
Non include un
Resetmetodo che può impostare l'enumeratore sulla posizione iniziale prima del primo elemento nell'intervallo. Il IEnumerator.Reset() metodo deve essere implementato come parte dell'interfaccia, ma la maggior parte degli implementatori genera un'eccezione o non fornisce alcuna implementazione.
Proprietà
| Nome | Descrizione |
|---|---|
| Current |
Ottiene un riferimento all'elemento nella posizione corrente dell'enumeratore. |
Metodi
| Nome | Descrizione |
|---|---|
| MoveNext() |
Sposta l'enumeratore all'elemento successivo di Span<T>. |
Implementazioni dell'interfaccia esplicita
| Nome | Descrizione |
|---|---|
| IDisposable.Dispose() |
Esegue attività definite dall'applicazione associate alla liberazione, al rilascio o alla reimpostazione di risorse non gestite. |
| IEnumerator.Current |
Ottiene l'elemento nella raccolta in corrispondenza della posizione corrente dell'enumeratore. |
| IEnumerator.Reset() |
Imposta l'enumeratore sulla posizione iniziale, ovvero prima del primo elemento della raccolta. |
| IEnumerator<T>.Current |
Ottiene l'elemento nella raccolta in corrispondenza della posizione corrente dell'enumeratore. |