Span<T>.Enumerator Yapı

Tanım

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

public: value class Span<T>::Enumerator
public ref struct Span<T>.Enumerator
type Span<'T>.Enumerator = struct
Public Structure Span(Of T).Enumerator

Tür Parametreleri

T
Devralma
Span<T>.Enumerator

Açıklamalar

C# dilinin C# foreach'i ve Her biri için... Visual Basic'teki sonraki yapı, numaralandırıcıların karmaşıklığını gizler. Numaralandırıcıyı doğrudan düzenlemek 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 Current tanımlanmamıştır. değerini Currentokumadan önce numaralandırıcıyı içindeki Span<T> ilk öğeye ilerletmek için çağrısında MoveNext bulunmalısınız.

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 MoveNext false.Span<T> Numaralandırıcı bu durumda olduğunda, sonraki çağrılar MoveNext da döndürülür false ve Current tanımsızdı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 alınan veriler de değiştirilebilir. Bu nedenle, bir span üzerinden numaralandırmak, doğası gereği 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öntemi yürütülmeden önce yayılmanın numaralandırılacağından ClearContents emin olmaz. Sonuç olarak, temel dizi span numaralandırması 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, aralığı listelemeden önce diziye erişimi eşitlerseniz, ClearContents yöntem numaralandırma sırasında temel alınan span verilerini değiştirmez. Örneğin, span'ı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'teki diğer bazı numaralandırıcı yapılarının aksine:Span<T>.Enumerator

  • veya IEnumerator<T> arabirimini IEnumerator uygulamaz. Bunun nedeni Span<T>.Enumerator bir başvuru yapısı olmasıdır.

  • Numaralandırıcıyı span'daki ilk öğeden önceki ilk konumuna ayarlayabilen bir Reset yöntem içermez. (Yöntemin IEnumerator.Reset() arabiriminin bir parçası olarak uygulanması gerekir, ancak çoğu uygulayıcı bir özel durum oluşturur veya uygulama sağlamaz.)

Özellikler

Current

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

Yöntemler

MoveNext()

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

Şunlara uygulanır