Span<T>.Enumerator Struktur

Definisi

Menyediakan enumerator untuk elemen 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

Jenis parameter

T
Warisan
Span<T>.Enumerator
Penerapan

Keterangan

Bahasa C# foreach bahasa C# dan Untuk Setiap... Selanjutnya konstruksi di Visual Basic menyembunyikan kompleksitas enumerator. Alih-alih secara langsung memanipulasi enumerator, menggunakan foreach atau For Each...Next direkomendasikan.

Awalnya, enumerator diposisikan sebelum elemen pertama dalam Span<T>. Pada posisi ini, Current tidak terdefinisi. Anda harus memanggil MoveNext untuk memajukan enumerator ke item pertama dalam Span<T> sebelum membaca nilai Current.

Current mengembalikan nilai yang sama hingga MoveNext dipanggil. MoveNext Current diatur ke item berikutnya di Span<T>.

Jika MoveNext melewati akhir Span<T>, MoveNext mengembalikan false. Ketika enumerator berada pada status ini, panggilan berikutnya untuk MoveNext juga kembali false dan Current tidak terdefinisi. Anda tidak dapat mengatur Current ke item pertama di Span<T> lagi; Anda harus membuat instans enumerator baru sebagai gantinya.

Enumerator tidak memiliki akses eksklusif ke Span<T>. Selain itu, data yang mendasar di mana rentang didasarkan juga dapat dimodifikasi. Oleh karena itu, menghitung melalui rentang secara intrinsik bukan prosedur aman utas. Untuk menjamin keamanan utas selama enumerasi, Anda harus menerapkan sinkronisasi Anda sendiri. Misalnya, kode berikut memiliki kondisi balapan. Ini tidak memastikan bahwa rentang akan dijumlahkan sebelum ClearContents metode dijalankan. Akibatnya, array yang mendasar dibersihkan selama enumerasi rentang:

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

Jika Anda menyinkronkan akses ke array sebelum menghitung rentang, seperti yang dilakukan versi EnumerateSpan metode yang direvisi dalam contoh berikut, ClearContents metode tidak memodifikasi data rentang yang mendasar selama enumerasi. Perhatikan bahwa contoh mengunci array yang mendasar di mana rentang didasarkan.

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

Tidak seperti beberapa struktur enumerator lainnya di .NET, Span<T>.Enumerator:

  • Tidak mengimplementasikan IEnumerator antarmuka atau IEnumerator<T> . Ini karena Span<T>.Enumerator adalah struktur ref.

  • Tidak termasuk Reset metode, yang dapat mengatur enumerator ke posisi awal sebelum elemen pertama dalam rentang. (Metode IEnumerator.Reset() harus diimplementasikan sebagai bagian dari antarmuka, tetapi sebagian besar implementor melemparkan pengecualian atau tidak memberikan implementasi.)

Properti

Nama Deskripsi
Current

Mendapatkan referensi ke item pada posisi enumerator saat ini.

Metode

Nama Deskripsi
MoveNext()

Memajukan enumerator ke item berikutnya dari Span<T>.

Implementasi Antarmuka Eksplisit

Nama Deskripsi
IDisposable.Dispose()

Melakukan tugas yang ditentukan aplikasi yang terkait dengan membebaskan, merilis, atau mengatur ulang sumber daya yang tidak dikelola.

IEnumerator.Current

Mendapatkan elemen dalam koleksi pada posisi enumerator saat ini.

IEnumerator.Reset()

Mengatur enumerator ke posisi awalnya, yaitu sebelum elemen pertama dalam koleksi.

IEnumerator<T>.Current

Mendapatkan elemen dalam koleksi pada posisi enumerator saat ini.

Berlaku untuk