Span<T>.Enumerator Estructura
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Proporciona un enumerador para los elementos de .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
Parámetros de tipo
- T
- Herencia
- Implementaciones
Comentarios
El foreach o For Each...Next .
Inicialmente, el enumerador se coloca antes del primer elemento de Span<T>. En esta posición, Current no está definido. Debe llamar MoveNext a para avanzar el enumerador al primer elemento de Span<T> antes de leer el valor de Current.
Current devuelve el mismo valor hasta MoveNext que se llama a . MoveNextestablece Current en el elemento siguiente de .Span<T>
Si MoveNext pasa el final de , Span<T>MoveNext devuelve false. Cuando el enumerador está en este estado, las llamadas posteriores a también devuelven MoveNextfalse y Current no están definidas. No se puede establecer Current en el primer elemento de nuevo Span<T> ; en su lugar, debe crear una nueva instancia del enumerador.
El enumerador no tiene acceso exclusivo a .Span<T> Además, también se pueden modificar los datos subyacentes en los que se basa el intervalo. Por lo tanto, la enumeración a través de un intervalo no es intrínsecamente un procedimiento seguro para subprocesos. Para garantizar la seguridad de los subprocesos durante la enumeración, debe implementar su propia sincronización. Por ejemplo, el código siguiente tiene una condición de carrera. No garantiza que el intervalo se enumerará antes de que se ejecute el ClearContents método . Como resultado, la matriz subyacente se borra durante la enumeración del intervalo:
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
Si sincroniza el acceso a la matriz antes de enumerar el intervalo, como hace la versión revisada del EnumerateSpan método en el ejemplo siguiente, el ClearContents método no modifica los datos de intervalo subyacentes durante la enumeración. Tenga en cuenta que el ejemplo bloquea la matriz subyacente en la que se basa el intervalo.
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
A diferencia de otras estructuras de enumerador en .NET, el Span<T>.Enumerator:
No implementa la IEnumerator interfaz o IEnumerator<T> . Esto se debe a Span<T>.Enumerator que es una estructura ref.
No incluye un
Resetmétodo , que puede establecer el enumerador en su posición inicial antes del primer elemento del intervalo. (El IEnumerator.Reset() método debe implementarse como parte de la interfaz, pero la mayoría de los implementadores inician una excepción o no proporcionan ninguna implementación).
Propiedades
| Nombre | Description |
|---|---|
| Current |
Obtiene una referencia al elemento en la posición actual del enumerador. |
Métodos
| Nombre | Description |
|---|---|
| MoveNext() |
Desplaza el enumerador al elemento siguiente de .Span<T> |
Implementaciones de interfaz explícitas
| Nombre | Description |
|---|---|
| IDisposable.Dispose() |
Realiza tareas definidas por la aplicación asociadas a la liberación, liberación o restablecimiento de recursos no administrados. |
| IEnumerator.Current |
Obtiene el elemento de la colección en la posición actual del enumerador. |
| IEnumerator.Reset() |
Establece el enumerador en su posición inicial, que es antes del primer elemento de la colección. |
| IEnumerator<T>.Current |
Obtiene el elemento de la colección en la posición actual del enumerador. |