Span<T>.Enumerator Struktura
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Poskytuje enumerátor pro prvky objektu 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
Parametry typu
- T
- Dědičnost
Poznámky
Foreach jazyka C# a For Each... Další konstruktor v jazyce Visual Basic skryje složitost enumerátorů. Místo přímé manipulace s enumerátorem se doporučuje použít nebo foreach
For Each...Next
.
Zpočátku je enumerátor umístěn před prvním prvkem v objektu Span<T>. Na této pozici Current není definován. Před čtením hodnoty Currentje nutné volatMoveNext, aby se enumerátor přepojí na první položku v objektu Span<T> .
Current vrátí stejnou hodnotu, dokud MoveNext není volána. MoveNext nastaví Current na další položku v objektu Span<T>.
Pokud MoveNext projde konec parametru Span<T>, MoveNext vrátí false
hodnotu . Pokud je enumerátor v tomto stavu, vrátí false
se MoveNext také další volání a Current není definováno. Nelze nastavit Current na první položku znovu; Span<T> místo toho musíte vytvořit novou instanci enumerátoru.
Enumerátor nemá výhradní přístup k objektu Span<T>. Kromě toho je možné upravit také podkladová data, na kterých je rozsah založen. Proto výčet přes rozpětí není vnitřně bezpečný postup pro přístup z více vláken. Abyste zajistili bezpečnost vláken během výčtu, musíte implementovat vlastní synchronizaci. Například následující kód má podmínku časování. Nezajistí, že span bude výčet před spuštěním ClearContents
metody. V důsledku toho se podkladové pole během výčtu rozsahu vymaže:
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
Pokud synchronizujete přístup k poli před výčtem rozsahu, jak to dělá revidovaná verze EnumerateSpan
metody v následujícím příkladu ClearContents
, metoda během výčtu neupravuje podkladová data spanu. Všimněte si, že příklad uzamkne podkladové pole, na kterém je rozsah založen.
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
Na rozdíl od některých jiných struktur enumerátoru v .NET:Span<T>.Enumerator
Neimplementuje IEnumerator rozhraní nebo IEnumerator<T> . Je to proto, že Span<T>.Enumerator se jedná o referenční strukturu.
Nezahrnuje metodu
Reset
, která může nastavit enumerátor na počáteční pozici před prvním prvkem v rozsahu. (Metoda IEnumerator.Reset() musí být implementována jako součást rozhraní, ale většina implementátorů buď vyvolá výjimku, nebo neposkytuje žádnou implementaci.)
Vlastnosti
Current |
Získá odkaz na položku na aktuální pozici enumerátoru. |
Metody
MoveNext() |
Posune enumerátor na další položku objektu Span<T>. |