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
- Наследование
- Реализации
Комментарии
C# foreach языка C# и For Each... Далее конструкция в Visual Basic скрывает сложность перечислителей. Вместо прямого управления перечислителем рекомендуется использовать foreach или For Each...Next использовать его.
Изначально перечислитель размещается перед первым элементом в элементе Span<T>. На этой позиции Current не определен. Перед чтением значения Currentнеобходимо вызвать MoveNext перечислитель к первому элементуSpan<T>.
Current возвращает то же значение до MoveNext вызова. MoveNext задает Current для следующего элемента в элементе Span<T>.
Если MoveNext проходит конец, Span<T>MoveNext возвращаетсяfalse. Когда перечислитель находится в этом состоянии, последующие вызовы MoveNext также возвращаются false и Current не определены. Нельзя задать Current первый элемент снова Span<T> . Вместо этого необходимо создать новый экземпляр перечислителя.
Перечислитель не имеет монопольного доступа к объекту 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:
Не реализует интерфейс или IEnumerator<T> не реализует IEnumerator интерфейс. Это связано с Span<T>.Enumeratorструктурой ссылок.
Не включает метод, который может задать перечислителю начальную
Resetпозицию перед первым элементом в диапазоне. (Метод IEnumerator.Reset() должен быть реализован как часть интерфейса, но большинство реализутелей либо вызывают исключение, либо не предоставляют реализацию.)
Свойства
| Имя | Описание |
|---|---|
| Current |
Возвращает ссылку на элемент в текущей позиции перечислителя. |
Методы
| Имя | Описание |
|---|---|
| MoveNext() |
Перемещает перечислитель к следующему элементу Span<T>элемента . |
Явные реализации интерфейса
| Имя | Описание |
|---|---|
| IDisposable.Dispose() |
Выполняет определяемые приложением задачи, связанные с освобождением, освобождением или сбросом неуправляемых ресурсов. |
| IEnumerator.Current |
Возвращает элемент в коллекции в текущей позиции перечислителя. |
| IEnumerator.Reset() |
Задает перечислителю начальную позицию, которая перед первым элементом в коллекции. |
| IEnumerator<T>.Current |
Возвращает элемент в коллекции в текущей позиции перечислителя. |