【发布时间】:2020-01-15 21:25:09
【问题描述】:
为什么我们不能在 foreach 循环中为局部变量赋值?
我知道这不会更新集合,因为我们只是在更改局部变量引用的对象。
如果您使用 while 循环实现相同的功能,它允许您更新局部变量。
class Program
{
static void Main(string[] args)
{
IEnumerable<string> enumerable = new List<string> { "a", "b", "c" };
//This foreach loop does not compile:
foreach (string item in enumerable)
{
item = "d"; //"cannot assign to item because it is a foreach iteration variable"
}
//The equivalent C# code does compile and allows assinging a value to item:
var enumerator = enumerable.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
string item = (string)enumerator.Current;
item = "d";
}
}
finally
{
enumerator.Dispose();
}
}
}
编辑:
这个问题与可能的重复问题不同,因为它询问为什么我们不能修改迭代变量,而在幕后它只是一个指向与enumerator.Current 相同的对象的局部变量。
【问题讨论】:
-
"等效的 C# 代码确实可以编译" 不!这 not 等同于您在
foreach循环中尝试执行的操作。在while循环中,您创建了对对象的new 引用,然后为其分配了不同的值。enumerator.Current = "d";也不起作用,出于同样的原因,enumerator.Current是只读的。 -
@AhmedAbdelhameed 这与 Caius Jard 下面的回答背道而驰。
-
在下面查看我的评论。另一方面,您的问题 is 类似于可能的重复问题,并且那里接受的答案回答了“为什么”问题。简单的答案是“因为迭代器是只读的”。欲了解更多信息,这里是another possible duplicate。专门检查那里的第二个答案,以了解有关它为什么是只读的更多信息。
-
@AhmedAbdelhameed 下面是一个示例,它显示了一个指向与 Current 相同的对象的局部变量:stackoverflow.com/questions/8898925/…
-
在这种情况下,标记的重复项应该足以解决您的问题,以及 Stack Overflow 上的许多其他类似问题。事实是,如果这真的是你的意思,那么这个问题并不是很有用,因为它总是会有相同的答案:“因为这是编译器强制执行的语言规则”。你也可以问诸如“为什么
internal隐藏我的程序集之外的代码中的成员”,或者“为什么使用yield return的方法必须具有IEnumerable、IEnumerator、@987654333 的返回类型@ 或IEnumerator<T>"?
标签: c# foreach iterator ienumerable ienumerator