英語で読む

次の方法で共有


Span<T>.Enumerator 構造体

定義

Span<T> の要素の列挙子を提供します。

C#
public ref struct Span<T>.Enumerator

型パラメーター

T
継承
Span<T>.Enumerator

注釈

C# のforeachとVisual BasicのFor Each...Next構造は、列挙子の複雑さを隠します。 列挙子を直接操作するのではなく、foreachまたはFor Each...Nextを使用することをお勧めします。

初期状態で、列挙子はSpan<T>内の最初の要素の前に配置されます。 この位置では、Current が未定義です。 Currentの値を読み取る前に、MoveNextを呼び出し、列挙子をSpan<T>の最初の項目に進める必要があります。

MoveNextが呼び出されるまで、Current は同じ値を返します。 MoveNextは、CurrentSpan<T>の次の項目に設定します。

MoveNextSpan<T>の末尾を超えた場合、MoveNextfalseを返します。 列挙子がこの状態にある場合、MoveNextの後続の呼び出しもfalseを返し、Currentは未定義になります。 Currentに再度Span<T>の最初の項目を設定することはできません。列挙子の新しいインスタンスを代わりに作成する必要があります。

列挙子はSpan<T>への排他アクセスがありません。 さらに、スパンの基になる基底データも変更できます。 そのため、スパンの列挙処理は、本質的にはスレッド セーフな手順ではありません。 列挙中のスレッド セーフを保証するには、独自の同期を実装する必要があります。 たとえば、次のコードには競合状態があります。 ClearContentsメソッドを実行する前に、スパンが列挙されることは保証されません。 その結果、スパンの列挙中に、基となる配列がクリアされます。

C#
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

次の例に挙げるEnumerateSpanメソッドの改訂版のように、スパンの列挙前に配列へのアクセスを同期する場合、ClearContentsメソッドは列挙中に、基底のスパンデータを変更しません。 この例がスパンの基になる、基底の配列をロックすることに注意してください。

C#
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

Span<T>.Enumeratorは、.NETの他の列挙子構造体とは異なります。

  • IEnumeratorまたはIEnumerator<T>インターフェイスを実装しません。 これは、Span<T>.Enumeratorref 構造体であるためです。

  • 列挙子をスパン内の最初の要素より前の初期位置に設定する、Resetメソッドは含まれません。 (IEnumerator.Reset()メソッドは、インターフェイスの一部として実装する必要がありますが、ほとんどの実装が例外をスローするか、実装されていません。)

プロパティ

Current

列挙子の現在位置にある項目への参照を取得します。

メソッド

MoveNext()

列挙子を Span<T> の次の項目に進めます。

適用対象

製品 バージョン
.NET Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7
.NET Standard 2.1