Span<T>.Enumerator 構造体

定義

Span<T> の要素の列挙子を提供します。Provides an enumerator for the elements of a Span<T>.

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

型パラメーター

T
継承
Span<T>.Enumerator

注釈

C# のforeachとVisual BasicのFor Each...Next構造は、列挙子の複雑さを隠します。The C# foreach of the C# language and the For Each...Next construct in Visual Basic hides the complexity of enumerators. 列挙子を直接操作するのではなく、foreachまたはFor Each...Nextを使用することをお勧めします。Instead of directly manipulating the enumerator, using foreach or For Each...Next is recommended.

初期状態で、列挙子はSpan<T>内の最初の要素の前に配置されます。Initially, the enumerator is positioned before the first element in the Span<T>. この位置では、Current は未定義です。At this position, Current is undefined. Currentの値を読み取る前に、MoveNextを呼び出し、列挙子をSpan<T>の最初の項目に進める必要があります。You must call MoveNext to advance the enumerator to the first item in the Span<T> before reading the value of Current.

MoveNextが呼び出されるまで、Current は同じ値を返します。Current returns the same value until MoveNext is called. MoveNextは、CurrentSpan<T>の次の項目に設定します。MoveNext sets Current to the next item in the Span<T>.

MoveNextSpan<T>の末尾を超えた場合、MoveNextfalseを返します。If MoveNext passes the end of the Span<T>, MoveNext returns false. 列挙子がこの状態にある場合、MoveNextの後続の呼び出しもfalseを返し、Currentは未定義になります。When the enumerator is at this state, subsequent calls to MoveNext also return false and Current is undefined. Currentに再度Span<T>の最初の項目を設定することはできません。列挙子の新しいインスタンスを代わりに作成する必要があります。You cannot set Current to the first item in the Span<T> again; you must create a new enumerator instance instead.

列挙子はSpan<T>への排他アクセスがありません。The enumerator does not have exclusive access to the Span<T>. さらに、スパンの基になる基底データも変更できます。In addition, the underlying data on which the span is based can also be modified. そのため、スパンの列挙処理は、本質的にはスレッド セーフな手順ではありません。Therefore, enumerating through a span is intrinsically not a thread-safe procedure. 列挙中のスレッドセーフを保証するには、独自の同期を実装する必要があります。To guarantee thread safety during enumeration, you must implement your own synchronization. たとえば、次のコードには競合状態があります。For example, the following code has a race condition. ClearContentsメソッドを実行する前に、スパンが列挙されることは保証されません。It does not ensure that the span will be enumerated before the ClearContents method executes. その結果、スパンの列挙中に、基となる配列がクリアされます。As a result, the underlying array is cleared during enumeration of the span:

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メソッドは列挙中に、基底のスパンデータを変更しません。If you synchronize access to the array before enumerating the span, as the revised version of the EnumerateSpan method does in the following example, the ClearContents method doesn't modify underlying span data during enumeration. この例がスパンの基になる、基底の配列をロックすることに注意してください。Note that the example locks the underlying array on which the span is based.

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の他の列挙子構造体とは異なります。Unlike some other enumerator structures in .NET, the Span<T>.Enumerator:

  • IEnumeratorまたはIEnumerator<T>インターフェイスを実装しません。Does not implement the IEnumerator or IEnumerator<T> interface. これは、Span<T>.Enumeratorref 構造体であるためです。This is because Span<T>.Enumerator is a ref struct.

  • 列挙子をスパン内の最初の要素より前の初期位置に設定する、Resetメソッドは含まれません。Does not include a Reset method, which can set the enumerator to its initial position before the first element in the span. (IEnumerator.Reset()メソッドは、インターフェイスの一部として実装する必要がありますが、ほとんどの実装が例外をスローするか、実装されていません。)(The IEnumerator.Reset() method must be implemented as part of the interface, but most implementors either throw an exception or provide no implementation.)

プロパティ

Current

列挙子の現在位置にある項目への参照を取得します。Gets a reference to the item at the current position of the enumerator.

メソッド

MoveNext()

列挙子を Span<T> の次の項目に進めます。Advances the enumerator to the next item of the Span<T>.

適用対象