Span<T>.Enumerator Estrutura
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
Fornece um enumerador para os elementos de um 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
- Herança
- Implementações
Comentários
O foreach do C# e o For Each... Em seguida construção em Visual Basic oculta a complexidade dos enumeradores. Em vez de manipular diretamente o enumerador, use foreach ou For Each...Next seja recomendado.
Inicialmente, o enumerador é posicionado antes do primeiro elemento no Span<T>. Nessa posição, Current é indefinido. Você deve chamar MoveNext para avançar o enumerador para o primeiro item antes Span<T> de ler o valor de Current.
Current retorna o mesmo valor até MoveNext ser chamado. MoveNext define Current o próximo item no Span<T>.
Se MoveNext passar o final do Span<T>, MoveNext retornará false. Quando o enumerador estiver nesse estado, as chamadas subsequentes também serão MoveNext retornadas false e Current indefinidas. Você não pode definir Current como o primeiro item novamente Span<T> ; você deve criar uma nova instância de enumerador.
O enumerador não tem acesso exclusivo ao Span<T>. Além disso, os dados subjacentes nos quais o intervalo se baseia também podem ser modificados. Portanto, enumerar por meio de um intervalo não é intrinsecamente um procedimento thread-safe. Para garantir a segurança do thread durante a enumeração, você deve implementar sua própria sincronização. Por exemplo, o código a seguir tem uma condição de corrida. Ele não garante que o intervalo será enumerado antes da execução do ClearContents método. Como resultado, a matriz subjacente é desmarcada durante a enumeração do 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
Se você sincronizar o acesso à matriz antes de enumerar o intervalo, como a versão revisada do EnumerateSpan método faz no exemplo a seguir, o método não modificará os ClearContents dados de intervalo subjacentes durante a enumeração. Observe que o exemplo bloqueia a matriz subjacente na qual o intervalo se baseia.
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
Ao contrário de algumas outras estruturas de enumerador em .NET, o Span<T>.Enumerator:
Não implementa a interface ou IEnumerator<T> a IEnumerator interface. Isso ocorre porque Span<T>.Enumerator é um struct ref.
Não inclui um
Resetmétodo, que pode definir o enumerador como sua posição inicial antes do primeiro elemento no intervalo. (O IEnumerator.Reset() método deve ser implementado como parte da interface, mas a maioria dos implementadores gera uma exceção ou não fornece nenhuma implementação.)
Propriedades
| Nome | Description |
|---|---|
| Current |
Obtém uma referência ao item na posição atual do enumerador. |
Métodos
| Nome | Description |
|---|---|
| MoveNext() |
Avança o enumerador para o próximo item do Span<T>. |
Implantações explícitas de interface
| Nome | Description |
|---|---|
| IDisposable.Dispose() |
Executa tarefas definidas pelo aplicativo associadas à liberação, liberação ou redefinição de recursos não gerenciados. |
| IEnumerator.Current |
Obtém o elemento na coleção na posição atual do enumerador. |
| IEnumerator.Reset() |
Define o enumerador como sua posição inicial, que é antes do primeiro elemento na coleção. |
| IEnumerator<T>.Current |
Obtém o elemento na coleção na posição atual do enumerador. |