为什么foreach循环在C#中只读

时间:2010-10-23 15:42:21

标签: c# loops

为什么foreach循环只读?我的意思是你可以获取数据,但不能增加++或减少 - 。它背后的任何原因? 是的我是初学者:)

〔实施例:

int[] myArray={1,2,3};
foreach (int num in myArray)
{
  num+=1;
}

3 个答案:

答案 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。而这个属性只有一个吸气剂,但没有吸气剂。

但如果它有一个二传手会怎么样?

  • 它适用于数组和列表
  • 对于像哈希表,有序列表这样的复杂容器,它不能很好地工作,因为更改会导致容器中的更大更改(例如重新排序),从而使迭代器无效。 (如果迭代器被修改以避免迭代器中的状态不一致,则大多数集合都会使迭代器失效。)
  • 在LINQ中它完全没有任何意义。例如,对于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.
}

但是,您无法在集合中添加或删除项目。