迭代语句 -for、foreach、do 和 while - C# reference

迭代语句重复执行语句或语句块。 当指定的布尔表达式的计算结果为for时,该执行其正文。

该foreach语句枚举集合的元素,并为集合的每个元素执行其正文。

该do语句有条件地执行其正文一次或多次。

while 语句:有条件地执行其主体零次或多次。

在迭代语句正文中的任何时间点,可以使用该语句中断循环break。 可以使用continue语句跳至循环中的下一次迭代。

for 语句

当指定的布尔表达式的计算结果为for时,该true语句执行语句或语句块。 以下示例显示了 for 语句,该语句在整数计数器小于 3 时执行其主体:

for (int i = 0; i < 3; i++)

{

Console.Write(i);

}

// Output:

// 012

前面的示例显示了语句的 for 元素:

“初始化表达式”部分仅在进入循环前执行一次。 通常,在该部分中声明并初始化本地循环变量。 无法从语句外部访问声明的 for 变量。

前面的示例中的初始化器部分声明并初始化整数计数器变量:

int i = 0

条件部分用于确定是否应执行循环中的下一次迭代。 如果计算结果为 true 或不存在,则执行下一次迭代;否则,将退出循环。

条件节必须是布尔表达式。

前面的示例中 的条件 部分检查计数器值是否小于 3:

i < 3

“迭代器”部分定义循环主体的每次执行后将执行的操作。

前面的示例中的 迭代器 部分递增计数器:

i++

循环的主体,必须是语句或语句块。

迭代器节可以包含以下语句表达式中的零个或多个,用逗号分隔:

前缀或后缀 递增 表达式,例如 ++i 或 i++

为 decrement 表达式添加前缀或后缀,如 --i 或 i--

分配

方法的调用

await表达式

使用new运算符创建对象

如果未在初始值设定项节中声明循环变量,也可以使用初始值设定项节中上述列表中的零个或多个表达式。 以下示例显示了初始值设定项和迭代器节的几个不太常见的用法:在初始值设定项节中为外部变量赋值、调用初始值设定项和迭代器节中的方法,以及更改迭代器节中两个变量的值:

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 接口的类型实例中的每个元素执行语句或语句块,如以下示例所示:

List 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 语句,该实例不实现任何接口:

Span 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 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 接口的集合类型。 在异步检索下一个元素时,循环的每个迭代都可能会暂停。 以下示例演示如何使用 await foreach 语句:

await foreach (var item in GenerateSequenceAsync())

{

Console.WriteLine(item);

}

还可以将 await foreach 语句与满足以下条件的任何类型的实例一起使用:

类型具有公共无参数的GetAsyncEnumerator方法。 该方法可以是类型的 扩展方法。

GetAsyncEnumerator 方法的返回类型具有公共 Current 属性和一个公共无参数的 MoveNextAsync 方法,其返回类型为 Task、ValueTask 或者是任何其他可等待类型,并且此类型的等待器中 GetResult 方法返回一个 bool 值。

默认情况下,流元素在捕获的上下文中进行处理。 如果要禁用上下文捕获,请使用 TaskAsyncEnumerableExtensions.ConfigureAwait 扩展方法。 有关同步上下文和捕获当前上下文的详细信息,请参阅 使用基于任务的异步模式。 有关异步流的详细信息,请参阅 异步流教程。

迭代变量的类型

可以使用 var 关键字 让编译器推断语句中 foreach 迭代变量的类型,如以下代码所示:

foreach (var item in collection) { }

注释

var编译器可以将类型推断为可为 null 的引用类型,具体取决于是否启用可为 null 的感知上下文以及初始化表达式的类型是否为引用类型。

有关详细信息,请参阅 隐式类型的局部变量。

还可以显式指定迭代变量的类型,如以下代码所示:

IEnumerable 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 执行一次或多次。 该 do 循环与 while 循环不同,该循环执行零次或多次。

以下示例显示了语句的 do 用法:

int n = 0;

do

{

Console.Write(n);

n++;

} while (n < 5);

// Output:

// 01234

while 语句

当指定的布尔表达式的计算结果为while时,该true语句执行语句或语句块。 由于该表达式是在每次执行循环之前计算的,因此循环 while 执行零次或多次。

while 循环不同于 do 循环(该循环执行 1 次或多次)。

以下示例显示了语句的 while 用法:

int n = 0;

while (n < 5)

{

Console.Write(n);

n++;

}

// Output:

// 01234

C# 语言规范

有关更多信息,请参阅 C# 语言规范的以下部分:

for 语句

foreach 语句

do 语句

while 语句

有关这些功能的详细信息,请参阅以下功能建议说明:

异步流

扩展 GetEnumerator 支持 foreach 循环

另请参阅

声明

迭代器

Copyright © 2022 世界杯吉祥物_世界杯日本队 - ctpapi.com All Rights Reserved.