Span<T>.Enumerator Yapı

Tanım

öğesinin öğeleri için bir Span<T>numaralandırıcı sağlar.

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

Tür Parametreleri

T
Devralma
Span<T>.Enumerator
Uygulamalar

Açıklamalar

C# dilinin C# foreach ve For Each... next yapısı Visual Basic numaralandırıcıların karmaşıklığını gizler. Numaralandırıcıyı doğrudan işlemek yerine veya For Each...Next kullanılması foreach önerilir.

Başlangıçta, numaralandırıcı içindeki ilk öğeden Span<T>önce konumlandırılır. Bu konumda tanımlanmamıştır Current . değerini Currentokumadan önce numaralandırıcıyı içindeki Span<T> ilk öğeye ilerletmek için aramanız MoveNext gerekir.

Current çağrılana kadar MoveNext aynı değeri döndürür. MoveNextiçindeki bir sonraki öğeye Span<T>ayarlarCurrent.

öğesinin sonunu geçerse MoveNext döndürür MoveNextfalse.Span<T> Numaralandırıcı bu durumdayken, sonraki çağrılar da döndürülür MoveNextfalse ve Current tanımlanmamıştır. içindeki ilk öğeye Span<T> yeniden ayarlayamazsınızCurrent; bunun yerine yeni bir numaralandırıcı örneği oluşturmanız gerekir.

Numaralandırıcının öğesine Span<T>özel erişimi yok. Ayrıca, yayılma alanının temel aldığı temel veriler de değiştirilebilir. Bu nedenle, bir span üzerinden numaralandırma, iş parçacığı açısından güvenli bir yordam değildir. Numaralandırma sırasında iş parçacığı güvenliğini garanti etmek için kendi eşitlemenizi uygulamanız gerekir. Örneğin, aşağıdaki kodun bir yarış durumu vardır. Yöntem yürütülmeden önce yayılma alanının numaralandırılacağından ClearContents emin olmaz. Sonuç olarak, temel dizi, yayılma alanının sabit listesi sırasında temizlenir:

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

Aşağıdaki örnekte yöntemin düzeltilmiş sürümünde EnumerateSpan olduğu gibi, yayılma alanını numaralandırmadan önce diziye erişimi eşitlerseniz, ClearContents yöntem numaralandırma sırasında temel alınan span verilerini değiştirmez. Örneğin, yayılma alanının temel aldığı temel diziyi kilitlediğini unutmayın.

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

.NET'daki diğer bazı numaralandırıcı yapılarının aksine Span<T>.Enumerator:

Özellikler

Name Description
Current

Numaralandırıcının geçerli konumundaki öğeye başvuru alır.

Yöntemler

Name Description
MoveNext()

Numaralandırıcıyı öğesinin sonraki öğesine ilerletir Span<T>.

Belirtik Arabirim Kullanımları

Name Description
IDisposable.Dispose()

Yönetilmeyen kaynakları serbest bırakma, serbest bırakma veya sıfırlama ile ilişkili uygulama tanımlı görevleri gerçekleştirir.

IEnumerator.Current

Koleksiyondaki öğesini numaralandırıcının geçerli konumunda alır.

IEnumerator.Reset()

Numaralandırıcıyı, koleksiyondaki ilk öğeden önceki ilk konumuna ayarlar.

IEnumerator<T>.Current

Koleksiyondaki öğesini numaralandırıcının geçerli konumunda alır.

Şunlara uygulanır