イテレーション ステートメント -
反復ステートメントは、ステートメントまたはステートメントのブロックを繰り返し実行します。
for
ステートメントは、指定されたブール式がtrue
評価される間、その本体を実行します。
foreach
ステートメントは、コレクションの要素を列挙し、コレクションの各要素の本体を実行します。
do
ステートメントは、本体を 1 回以上条件付きで実行します。
while
ステートメントは、本体を 0 回以上条件付きで実行します。
反復ステートメントの本体内の任意の時点で、 break
ステートメントを使用してループから抜け出すことができます。
continue
ステートメントを使用して、ループ内の次のイテレーションにステップ インできます。
for
ステートメント
for
ステートメントはステートメントまたはステートメント ブロックを実行しますが、指定されたブール式はtrue
と評価されます。 次の例は、整数カウンターが 3 未満の場合に本体を実行する for
ステートメントを示しています。
for (int i = 0; i < 3; i++)
{
Console.Write(i);
}
// Output:
// 012
前の例は、 for
ステートメントの要素を示しています。
ループに入る前に 1 回だけ実行される 初期化子 セクション。 通常は、そのセクションでローカル ループ変数を宣言して初期化します。 宣言された変数は、
for
ステートメントの外部からアクセスできません。前の例の 初期化子 セクションでは、整数カウンター変数を宣言して初期化します。
int i = 0
ループ内の次の反復を実行する必要があるかどうかを決定する 条件 セクション。
true
に評価された場合、または存在しない場合は、次のイテレーションが実行されます。それ以外の場合は、ループが終了します。 条件セクションはブール式である必要があります。前の例の condition セクションでは、カウンター値が 3 未満かどうかを確認します。
i < 3
ループ本体の各実行後の動作を定義する 反復子 セクション。
前の例の 反復子 セクションは、カウンターをインクリメントします。
i++
ループの本体。ステートメントまたはステートメントのブロックである必要があります。
iterator セクションには、次のステートメント式のうち 0 個以上をコンマで区切って含めることができます。
- プレフィックスまたは後置 インクリメント 式 (
++i
やi++
- 前置または後置のデクリメント式 (
--i
、i--
など) - 割り当て
- メソッドの呼び出し
-
await
式 -
new
演算子を使用したオブジェクトの作成
初期化子セクションでループ変数を宣言しない場合は、初期化子セクションの前のリストの 0 個以上の式を使用することもできます。 次の例は、初期化子セクションと反復子セクションのあまり一般的でない使用法をいくつか示しています。初期化子セクションの外部変数に値を割り当てる、初期化子セクションと反復子セクションの両方でメソッドを呼び出す、反復子セクションで 2 つの変数の値を変更する、
int i;
int j = 3;
for (i = 0, Console.WriteLine($"Start: i={i}, j={j}"); i < j; i++, j--, Console.WriteLine($"Step: i={i}, j={j}"))
{
//...
}
// Output:
// Start: i=0, j=3
// Step: i=1, j=2
// Step: i=2, j=1
for
ステートメントのすべてのセクションは省略可能です。 たとえば、次のコードは無限 for
ループを定義します。
for ( ; ; )
{
//...
}
foreach
ステートメント
foreach
ステートメントは、次の例に示すように、System.Collections.IEnumerableまたはSystem.Collections.Generic.IEnumerable<T> インターフェイスを実装する型のインスタンス内の各要素に対してステートメントまたはステートメントブロックを実行します。
List<int> fibNumbers = new() { 0, 1, 1, 2, 3, 5, 8, 13 };
foreach (int element in fibNumbers)
{
Console.Write($"{element} ");
}
// Output:
// 0 1 1 2 3 5 8 13
foreach
ステートメントは、これらの型に限定されません。 これは、次の条件を満たす任意の型のインスタンスと共に使用できます。
- 型には、パラメーターなしのパブリック
GetEnumerator
メソッドがあります。GetEnumerator
メソッドには、型の拡張メソッドを指定できます。 -
GetEnumerator
メソッドの戻り値の型には、パブリックCurrent
プロパティと、戻り値の型がMoveNext
パブリック パラメーターなしのbool
メソッドがあります。
次の例では、インターフェイスを実装しないforeach
型のインスタンスでSystem.Span<T> ステートメントを使用します。
Span<int> numbers = [3, 14, 15, 92, 6];
foreach (int number in numbers)
{
Console.Write($"{number} ");
}
// Output:
// 3 14 15 92 6
列挙子のCurrent
プロパティが参照戻り値を返す場合 (ref T
がコレクション要素の型であるT
)、次の例に示すように、ref
またはref readonly
修飾子を使用して反復変数を宣言できます。
Span<int> storage = stackalloc int[10];
int num = 0;
foreach (ref int item in storage)
{
item = num++;
}
foreach (ref readonly var item in storage)
{
Console.Write($"{item} ");
}
// Output:
// 0 1 2 3 4 5 6 7 8 9
foreach
ステートメントのソース コレクションが空の場合、foreach
ステートメントの本文は実行されず、スキップされません。
foreach
ステートメントが null
に適用されると、NullReferenceException が発生します。
await foreach
await foreach
ステートメントを使用して、データの非同期ストリーム (つまり、IAsyncEnumerable<T> インターフェイスを実装するコレクション型) を使用できます。 ループの各反復処理は中断され、次の要素は非同期的に取得されます。 次の例は、 await foreach
ステートメントの使用方法を示しています。
await foreach (var item in GenerateSequenceAsync())
{
Console.WriteLine(item);
}
await foreach
ステートメントは、次の条件を満たす任意の型のインスタンスと共に使用することもできます。
- 型には、パラメーターなしのパブリック
GetAsyncEnumerator
メソッドがあります。 そのメソッドには、型の 拡張メソッドを指定できます。 -
GetAsyncEnumerator
メソッドの戻り値の型に、パブリックCurrent
プロパティと、パラメーターなしのパブリックMoveNextAsync
メソッドがあり、そのメソッドの戻り値の型がTask<bool>
、ValueTask<bool>
、または awaiter のGetResult
メソッドがbool
値を返すその他の待機可能型のいずれかです。
既定では、ストリーム要素はキャプチャされたコンテキストで処理されます。 コンテキストのキャプチャを無効にする場合は、 TaskAsyncEnumerableExtensions.ConfigureAwait 拡張メソッドを使用します。 同期コンテキストと現在のコンテキストのキャプチャの詳細については、「 タスク ベースの非同期パターンの使用」を参照してください。 非同期ストリームの詳細については、非同期ストリームの チュートリアルを参照してください。
反復変数の型
var
キーワードを使用すると、次のコードに示すように、コンパイラが foreach
ステートメント内の反復変数の型を推論できます。
foreach (var item in collection) { }
注
var
の型は、null 許容対応コンテキストが有効かどうか、および初期化式の型が参照型かどうかに応じて、コンパイラが null 許容参照型として推論できます。
詳細については、 暗黙的に型指定されたローカル変数を参照してください。
次のコードに示すように、反復変数の型を明示的に指定することもできます。
IEnumerable<T> collection = new T[5];
foreach (V item in collection) { }
上記の形式では、コレクション要素の T
型は、反復変数の型 V
に暗黙的または明示的に変換できる必要があります。 実行時に T
から V
への明示的な変換が失敗した場合、 foreach
ステートメントは InvalidCastExceptionをスローします。 たとえば、 T
が非シール クラス型の場合、 V
は、 T
が実装していないインターフェイス型であっても、任意のインターフェイス型にすることができます。 実行時に、コレクション要素の型は、 T
から派生し、実際に V
を実装する型である可能性があります。 そうでない場合は、InvalidCastException が投げられます。
do
ステートメント
do
ステートメントはステートメントまたはステートメント ブロックを実行しますが、指定されたブール式はtrue
と評価されます。 その式はループの各実行後に評価されるため、 do
ループは 1 回以上実行されます。
do
ループは、0 回以上実行されるwhile
ループとは異なります。
次の例は、 do
ステートメントの使用方法を示しています。
int n = 0;
do
{
Console.Write(n);
n++;
} while (n < 5);
// Output:
// 01234
while
ステートメント
while
ステートメントはステートメントまたはステートメント ブロックを実行しますが、指定されたブール式はtrue
と評価されます。 その式はループの各実行前に評価されるため、 while
ループは 0 回以上実行されます。
while
ループは、1 回以上実行されるdo
ループとは異なります。
次の例は、 while
ステートメントの使用方法を示しています。
int n = 0;
while (n < 5)
{
Console.Write(n);
n++;
}
// Output:
// 01234
C# 言語仕様
詳細については、「C# 言語仕様」の次のセクションを参照してください。
これらの機能の詳細については、機能の提案に関する次の記述を参照してください。
こちらも参照ください
.NET