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 # 语言的 c # foreachFor Each .。。 Visual Basic 中的下一个构造隐藏了枚举器的复杂性。The C# foreach of the C# language and the For Each...Next construct in Visual Basic hides the complexity of enumerators. 建议使用或,而不是直接操作枚举器 foreach For Each...NextInstead 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>. 在此位置上,未定义 CurrentAt this position, Current is undefined. 在读取的 MoveNext 值之前,必须调用以将枚举器前进到中的第一项 Span<T> CurrentYou must call MoveNext to advance the enumerator to the first item in the Span<T> before reading the value of Current.

Current 在调用之前,返回相同的值 MoveNextCurrent returns the same value until MoveNext is called. MoveNext 设置 Current 为中的下一项 Span<T>MoveNext sets Current to the next item in the Span<T>.

如果 MoveNext 传递的末尾,则 Span<T> MoveNext 返回 falseIf 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. 它不会确保在执行方法之前枚举跨距 ClearContentsIt 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

不同于 .NET 中的其他枚举器结构, Span<T>.EnumeratorUnlike some other enumerator structures in .NET, the Span<T>.Enumerator:

  • 不实现 IEnumeratorIEnumerator<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>.

适用于