Span<T>.Enumerator Struktura

Definice

Poskytuje enumerátor pro prvky objektu 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

Parametry typu

T
Dědičnost
Span<T>.Enumerator
Implementuje

Poznámky

Jazyk C# foreach jazyka C# a For Each... Konstruktor Další v Visual Basic skryje složitost výčtů. Místo přímé manipulace s enumerátorem použijte foreach nebo For Each...Next se doporučuje.

Zpočátku je enumerátor umístěn před prvním prvkem v objektu Span<T>. V této pozici Current není definováno. Je třeba volat MoveNext , aby se enumerátor přepošli na první položku v Span<T> předčítání hodnoty Current.

Current vrátí stejnou hodnotu, dokud MoveNext se nevolá. MoveNext nastaví Current na další položku v objektu Span<T>.

Pokud MoveNext předá konec Span<T>, MoveNext vrátí false. Pokud je enumerátor v tomto stavu, následná volání, která se MoveNext mají vrátit false a Current je nedefinovaná. Nelze nastavit Current na první položku znova 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 rozsah není vnitřně bezpečným postupem pro přístup z více vláken. Pokud chcete zaručit 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í. Před provedením ClearContents metody se nezajistí, že rozsah bude vyčíslena. V důsledku toho se podkladové pole vymaže během výčtu rozsahu:

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 před výčtem rozsahu synchronizujete přístup k poli, protože revidovaná verze EnumerateSpan metody v následujícím příkladu ClearContents neupravuje podkladová data spanu během výčtu. 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í ani IEnumerator<T> rozhraní. Je to proto, že Span<T>.Enumerator jde o strukturu ref.

  • Nezahrnuje metodu Reset , která může nastavit enumerátor na počáteční pozici před prvním prvkem v rozpětí. (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

Name Description
Current

Získá odkaz na položku na aktuální pozici enumerátoru.

Metody

Name Description
MoveNext()

Přejde enumerátor na další položku objektu Span<T>.

Explicitní implementace rozhraní

Name Description
IDisposable.Dispose()

Provádí úlohy definované aplikací související s uvolněním, uvolněním nebo resetováním nespravovaných prostředků.

IEnumerator.Current

Získá prvek v kolekci na aktuální pozici enumerátoru.

IEnumerator.Reset()

Nastaví enumerátor na počáteční pozici, která je před prvním prvkem v kolekci.

IEnumerator<T>.Current

Získá prvek v kolekci na aktuální pozici enumerátoru.

Platí pro