为什么foreach循环只读?我的意思是你可以获取数据,但不能增加++或减少 - 。它背后的任何原因? 是的我是初学者:)
〔实施例:
int[] myArray={1,2,3};
foreach (int num in myArray)
{
num+=1;
}
答案 0 :(得分:9)
这是因为foreach意味着迭代一个容器,确保每个项目只被访问一次,而不更改容器,以避免讨厌的副作用。
请参阅:foreach in MSDN
如果你的意思是为什么像整数这样的元素的改变不会影响整数的容器,那么这是因为在这种情况下迭代的变量将是一个值类型并被复制,例如:
// Warning: Does not compile
foreach (int i in ints)
{
++i; // Would not change the int in ints
}
即使迭代变量是一个引用类型,其操作返回一个新对象,你也不会改变原始集合,你只需要在大多数时间重新分配给这个变量:
// Warning: Does not compile
foreach (MyClass ob in objs)
{
ob=ob+ob; // Reassigning to local ob, not changing the one from the original
// collection of objs
}
以下示例可能通过调用 mutating 方法实际修改原始集合中的对象:
// Warning: Does not compile
foreach (MyClass ob in objs)
{
ob.ChangeMe(); // This could modify the object in the original collection
}
为避免混淆价值与参考类型和上述情景(以及与优化相关的一些原因),MS选择制作迭代变量readonly
。
答案 1 :(得分:9)
因为当前元素是按值返回的(即复制)。修改副本是没用的。如果它是引用类型,则可以修改该对象的内容,但不能替换引用。
也许您应该阅读IEnumerable<T>
和IEnumerator<T>
的文档。这应该让它更清晰。最重要的一点是,IEnumerable<T>
具有Current
类型的属性T
。而这个属性只有一个吸气剂,但没有吸气剂。
但如果它有一个二传手会怎么样?
select(x=>f(x))
,值是函数的结果,并且没有关联的永久存储。yield return
语法编写的迭代器无论是答案 2 :(得分:1)
foreach
旨在仅访问集合中的每个项目一次,并且不使用显式的“循环索引”;如果您想要更多地控制循环并拥有循环索引,请使用for
。
编辑:您可以在foreach
循环内更改正在迭代的集合中的项目。例如:
foreach(Chair ch in mychairs)
{
ch.PaintColour = Colour.Green; //this alters the chair object *in* the collection.
}
但是,您无法在集合中添加或删除项目。