2010-10-23 93 views
13

为什么foreach循环只读?我的意思是你可以获取数据,但不能增加++或减少 - 。背后有什么理由? 是的,我是一个初学者:)为什么foreach循环只读在C#

〔实施例:

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

你是什么意思while循环被只读的意思吗? while循环是一个构造;它既不是只读也不是读写。你可以发布一些代码和/或澄清你的问题吗?谢谢。 – CesarGon 2010-10-23 15:46:24

+1

我想他是在讨论迭代变量,如在foreach中(项目theItem inItemList)...该项目不能分配给。 – 2010-10-23 15:47:59

+0

他现在澄清了这个问题:他在谈论foreach而不是while。 – CesarGon 2010-10-23 15:48:46

回答

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 
} 

下面的例子有实际上通过调用突变方法修改原始集合中的对象的电势:

// Warning: Does not compile 
foreach (MyClass ob in objs) 
{ 
    ob.ChangeMe(); // This could modify the object in the original collection 
} 

为了避免关于值Vs引用类型的混乱和上面提到的场景(以及与优化有关的一些原因),MS选择使得迭代readonly的变量。

1

foreach被设计为访问集合中的每个项目一次,而不使用明确的“循环索引”;如果您想要更多地控制循环并获得循环索引,请使用for

编辑:您可以更改在foreach循环内迭代的集合中的项目。例如:

foreach(Chair ch in mychairs) 
{ 
    ch.PaintColour = Colour.Green; //this alters the chair object *in* the collection. 
} 

但是,您不能将项目添加到集合或从集合中删除项目。

+0

实际上,您无法修改迭代变量引用的对象的字段/属性。 – 2010-10-23 16:09:10

+0

@Michael:我发布的代码适合我。我正在使用.NET 3.5和Visual Studio 2008. – CesarGon 2010-10-23 16:23:03

7

因为当前元素是由值返回(即复制)。而修改副本是没用的。如果它是引用类型,则可以修改该对象的内容,但不能替换该引用。

也许您应该阅读文档IEnumerable<T>IEnumerator<T>。这应该更清楚。最重要的是IEnumerable<T>有一个Current类型T。而这个属性只有一个getter,但没有setter。

但是如果它有一个setter,会发生什么?

  • 它将与阵列很好地工作和列表
  • 它不会与像散列表复杂容器很好地工作,有序列表由于变化引起的容器较大变化(例如重排序),因此,无效信号迭代器。 (如果迭代器被修改以避免迭代器中的状态不一致,大多数集合将使迭代器无效。)
  • 在LINQ中它根本没有任何意义。例如对于select(x=>f(x)),这些值是函数的结果并且没有关联的永久存储。
  • 迭代器写入与yield return语法它没有意义或者
+0

“修改副本是没用的。”如果我想要做一些工作,比如列表中所有数字的平方和?它可以通过只读限制来完成,但修改副本通常很有用。 – raylu 2014-11-26 08:51:20