Span<T>.Enumerator 結構

定義

提供一個 元素的 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

類型參數

T
繼承
Span<T>.Enumerator
實作

備註

C# 語言中的 C# foreach 以及 Foreach...」Next Visual Basic 中的結構隱藏了列舉器的複雜性。 建議不要直接操作列舉器,而是使用 foreachFor Each...Next

最初,列舉器會被放置在 Span<T>。 在此位置, Current 未定義。 你必須先呼叫MoveNext,讓列舉員在讀取 的值Current之前,先將列舉器推進到第一個項目Span<T>

Current 回傳相同的值直到 MoveNext 被呼叫。 MoveNext 設定 Current 為 中的下一個項目 Span<T>

MoveNext 通過 Span<T>MoveNext 則返回 false。 當列舉器處於此狀態時,後續的回MoveNextfalseCurrent呼叫也為未定義。 你不能在 back 裡Span<T>Current成第一個項目;你必須建立一個新的 enumerator 實例。

列舉器並非對 的專屬存取 Span<T>權。 此外,該跨度所依據的底層資料也可以被修改。 因此,透過一個跨度枚舉本質上並非執行緒安全的程序。 為了確保列舉時執行緒的安全,你必須自行實作同步功能。 例如,以下程式碼有競賽條件。 它不保證在方法執行前 ClearContents 會列舉該區間。 因此,底層陣列在枚舉該範圍時會被清除:

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

如果你在列舉範圍前同步陣列存取,如以下範例中修訂版本 EnumerateSpan 的方法所做的,該 ClearContents 方法在列舉時不會修改底層的範圍資料。 請注意,範例鎖定了該張成所依據的底層陣列。

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中其他一些列舉子結構不同,Span<T>.Enumerator

屬性

名稱 Description
Current

會取得列舉器當前位置的項目參考。

方法

名稱 Description
MoveNext()

將列舉器推進到下一個項目 Span<T>

明確介面實作

名稱 Description
IDisposable.Dispose()

執行與釋放、釋放或重置未管理資源相關的應用程式定義任務。

IEnumerator.Current

取得集合中位於列舉值目前位置的專案。

IEnumerator.Reset()

將列舉值設定為其初始位置,也就是集合中第一個專案之前。

IEnumerator<T>.Current

取得集合中位於列舉值目前位置的專案。

適用於