Span<T>.Enumerator Structure
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
Fournit un énumérateur pour les éléments d’un Span<T>.
public: value class Span<T>::Enumerator
public ref struct Span<T>.Enumerator
type Span<'T>.Enumerator = struct
Public Structure Span(Of T).Enumerator
Paramètres de type
- T
- Héritage
Remarques
Foreach C# du langage C# et For Each... La construction suivante dans Visual Basic masque la complexité des énumérateurs. Au lieu de manipuler directement l’énumérateur, l’utilisation foreach
ou For Each...Next
l’utilisation est recommandée.
Initialement, l’énumérateur est positionné avant le premier élément du Span<T>. À cette position, Current n'est pas défini. Vous devez appeler MoveNext pour faire avancer l’énumérateur vers le premier élément de l’avant Span<T> de lire la valeur de Current.
Current retourne la même valeur jusqu’à ce qu’elle MoveNext soit appelée. MoveNext définit Current l’élément suivant dans le Span<T>.
Si MoveNext elle passe la fin de l’objet Span<T>, MoveNext retourne false
. Lorsque l’énumérateur se trouve à cet état, les appels suivants à MoveNext retourner false
et Current ne sont pas définis. Vous ne pouvez pas définir Current le premier élément à nouveau ; vous devez créer une instance d’énumérateur à la Span<T> place.
L’énumérateur n’a pas d’accès exclusif au Span<T>. En outre, les données sous-jacentes sur lesquelles l’étendue est basée peuvent également être modifiées. Par conséquent, l’énumération à travers une étendue n’est intrinsèquement pas une procédure thread-safe. Pour garantir la sécurité des threads pendant l’énumération, vous devez implémenter votre propre synchronisation. Par exemple, le code suivant a une condition de concurrence. Elle ne garantit pas que l’étendue sera énumérée avant l’exécution de la ClearContents
méthode. Par conséquent, le tableau sous-jacent est effacé pendant l’énumération de l’étendue :
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 vous synchronisez l’accès au tableau avant d’énumérer l’étendue, comme le fait la version révisée de la méthode dans l’exemple suivant, la ClearContents
méthode ne modifie pas les données d’étendue sous-jacentes pendant l’énumérationEnumerateSpan
. Notez que l’exemple verrouille le tableau sous-jacent sur lequel l’étendue est basée.
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
Contrairement à d’autres structures d’énumérateur dans .NET, les Span<T>.Enumeratoréléments suivants :
N’implémente pas l’interface ou IEnumerator<T> l’interfaceIEnumerator. En effet Span<T>.Enumerator , il s’agit d’un struct ref.
N’inclut pas de
Reset
méthode, qui peut définir l’énumérateur sur sa position initiale avant le premier élément de l’étendue. (La IEnumerator.Reset() méthode doit être implémentée dans le cadre de l’interface, mais la plupart des implémenteurs lèvent une exception ou ne fournissent aucune implémentation.)
Propriétés
Current |
Obtient une référence à l’élément à la position actuelle de l’énumérateur. |
Méthodes
MoveNext() |
Avance l’énumérateur à l’élément suivant de Span<T>. |