这2个片段是否完全相同?

时间:2011-12-22 13:06:36

标签: c# foreach

我有这段代码:

foreach (object obj in _Destinations)
{
    obj = _ItemsSource;
}

正在生成错误

  

无法分配给'obj',因为它是'foreach迭代变量'

所以我用以下代码“圈出”了这个问题:

for (int i = 0; i < _Destinations.Count; i++)
{
    _Destinations[i] = _ItemsSource;
}

这适用于我的实际情况,但我不确定这对于任何类型的对象都是完全相同的。是这样的吗?

编辑:_Destinations是List<object>

5 个答案:

答案 0 :(得分:2)

这绝对是同样的事情:对于初学者,第二个有用,而第一个没有:)

第一个代码段不起作用的原因是因为它使用_Distance列表中的迭代器,并且无法通过IEnumerable<T>的迭代器分配给原始集合。第二个代码段使用[index]来访问基础列表或数组。这种结构允许阅读和写作;这就是它起作用的原因。

就相同顺序访问列表或数组的所有元素而言,两种结构都是相同的。

答案 1 :(得分:1)

我猜_Destinations是值类型的集合。

forach循环为循环的每个“圆”创建它迭代的元素的副本,并且最终只更改副本,而不会更改您正在迭代的实际集合。

for循环中,您将使用索引更改实际集合。

所以不,它们不是严格等同的。

对于参考类型,这在同一意义上无关紧要,因为集合中的元素和foreach 引用创建的副本都是同一个对象,并且正确的对象将被更改,无论您是否使用foreachfor循环(至少当你像这样使用它时)

答案 2 :(得分:1)

它显然不是一回事,因为你的结果不同!一个得到错误,另一个有效。

避免这种差异,你的第一个错误是修改foreach中的循环变量是非法的结果。你的第二个设法通过迭代for并分配到索引位置来完全回避问题。只要您具有可写的可索引集合(例如列表或数组),这将继续适用于您。如果您正在使用不可写或不可索引的集合,例如简单的IEnumerableReadOnlyCollection<T>,那么您将无法使用此机制来覆盖元素,如序列是只读的。

答案 3 :(得分:1)

Foreach适用于任何IEnumerable,这是一个对象的最基本的契约,它是某种其他目标的聚合,列表,集合......。 IEnumerable不提供覆盖聚合中的项目的工具,甚至不提供或删除。在IEnumerable中,也没有索引的概念。因此,您无法为foreach迭代变量赋值。

另一个代码片段需要一个实现IList的集合,这是一个更具体的契约,一个允许集合操作并且还有一个索引概念。因此,第二个代码段可以正常工作。

第二个例子中的IList理论上可以实现一个枚举,它不会按索引升序排列,但这种可能性很小,因此你可以将两种迭代技术视为相同。

答案 4 :(得分:0)

您应该阅读IEnumerableIEnumerator,以使foreach数据块正常运行。