Span<T>.Enumerator 構造体
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
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# 言語の C# foreach と For Each...次Visual Basicのコンストラクトでは、列挙子の複雑さが隠されます。 列挙子を直接操作する代わりに、 foreach または For Each...Next を使用することをお勧めします。
最初は、列挙子は Span<T>の最初の要素の前に配置されます。 この位置では、 Current は未定義です。 MoveNextを呼び出して、Currentの値を読み取る前に、列挙子をSpan<T>の最初の項目に進める必要があります。
Current は、 MoveNext が呼び出されるまで同じ値を返します。 MoveNext は、 Current を Span<T>内の次の項目に設定します。
MoveNextがSpan<T>の末尾を通過した場合、MoveNextはfalseを返します。 列挙子がこの状態の場合、後続の MoveNext 呼び出しでも false が返され、 Current は未定義になります。
Span<T>の最初の項目にCurrentを再度設定することはできません。代わりに新しい列挙子インスタンスを作成する必要があります。
列挙子は、 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またはIEnumerator<T> インターフェイスを実装しません。 これは、 Span<T>.Enumerator が ref 構造体であるためです。
列挙子をスパンの最初の要素の前の最初の位置に設定できる
Resetメソッドは含まれません。 ( IEnumerator.Reset() メソッドはインターフェイスの一部として実装する必要がありますが、ほとんどの実装者は例外をスローするか、実装を提供しません)。
プロパティ
| 名前 | 説明 |
|---|---|
| Current |
列挙子の現在位置にある項目への参照を取得します。 |
メソッド
| 名前 | 説明 |
|---|---|
| MoveNext() |
列挙子を Span<T>の次の項目に進めます。 |
明示的なインターフェイスの実装
| 名前 | 説明 |
|---|---|
| IDisposable.Dispose() |
アンマネージド リソースの解放、解放、またはリセットに関連付けられているアプリケーション定義のタスクを実行します。 |
| IEnumerator.Current |
列挙子の現在位置にあるコレクション内の要素を取得します。 |
| IEnumerator.Reset() |
列挙子を最初の位置 (コレクション内の最初の要素の前) に設定します。 |
| IEnumerator<T>.Current |
列挙子の現在位置にあるコレクション内の要素を取得します。 |