foreach
枚举任何实现IEnumerable
、IEnumerable<T>
、IEnumerator
或IEnumerator<T>
的对象(或实际上任何其类实现兼容Current
属性和MoveNext()
方法的对象)。的语法foreach
是:
foreach (type variable in enumerable) { ... }
type
是新variable
变量的类型。(如果您已经有一个现有的变量要使用,则省略类型。)
循环体将为可枚举中的每个对象执行,迭代变量(此处variable
)将包含每次迭代的对象。
for
更通用,并遵循以下模式:
for (initial-statements; loop-condition; post-iteration-actions) {
body
}
这几乎完全等同于:
initial-statements
while (loop-condition) {
body
post-iteration-actions
}
for
在处理数组时,您可能会看到一个循环,例如:
for (int index = 0; index < array.Length; index++) {
Console.WriteLine(array[index]);
}
这与以下内容相同:
{
int index = 0;
while (index < array.Length) {
Console.WriteLine(array[index]);
index++;
}
}
(请注意,foreach
编译器对使用 over 数组进行了优化,以使用类似的基于索引的迭代,因为这样更快。因此,在枚举数组时,所有三种方法都应该具有等效的性能和运行时语义。)
更多信息,如果你想要的话:
foreach
实际上只是语法糖,可以很容易地翻译成while
循环。
foreach (object x in y) {
Console.WriteLine(x);
}
这实际上意味着:
var enumerator = y.GetEnumerator();
try {
object x; // See footnote 1
while (enumerator.MoveNext()) {
x = enumerator.Current;
Console.WriteLine(x);
}
} finally {
((IDisposable)enumerator).Dispose();
}
除了enumerator
变量没有名称并且对您隐藏。
存在的原因很明显foreach
。你今天在任何地方使用它,否则你将不得不编写这个非常冗长的样板代码。 foreach
为您处理所有事情——获取枚举器,MoveNext()
在每次迭代中进行测试,提取枚举器的当前值,并在迭代完成后处理枚举器。
1这个变量实际上是在循环内部进行语义声明的,从 C# 5 开始。此示例适用于 C# 4 和更早版本。