更新结构在foreach循环在C#

问题描述:

我有这样的代码(C#):更新结构在foreach循环在C#

using System.Collections.Generic; 

namespace ConsoleApplication1 
{ 
    public struct Thing 
    { 
     public string Name; 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<Thing> things = new List<Thing>(); 
      foreach (Thing t in things) // for each file 
      { 
       t.Name = "xxx"; 
      } 
     } 
    } 
} 

它不会编译。
错误是:

Cannot modify members of 't' because it is a 'foreach iteration variable' 

如果我改变Thingclass,而不是一个struct,但是,它编译。

请有人可以解释发生了什么?

+0

相关问题http://*.com/questions/1538301/c-does-foreach-iterate-by-reference/1538316#1538316 – 2009-10-23 10:42:24

+0

感谢您的链接,布赖恩。 – 2009-10-23 11:26:47

或多或少它所说的,编译器不会让你在foreach中更改(部分)循环变量。

只需使用:

for(int i = 0; i < things.Count; i+= 1) // for each file 
{ 
    things[i].Name = "xxx"; 
} 

和它的作品时Thing是一类,因为那么你的循环var是一个参考,你只更改引用的对象,而不是引用本身。

+0

正是我在找的!谢谢,Henk :) – 2009-10-23 10:39:55

结构不是引用类型,而是值类型。

如果你将有一个class而不是structThing,foreach循环会为您创建一个引用变量,这将指向您列表中的正确元素。但由于它是一种值类型,它只能在Thing的副本上运行,在这种情况下,它是迭代变量。

+0

是的,这是相关的。因为它是一个值类型,整个结构是循环变量,因此它的任何部分都不能被修改。 – 2009-10-23 10:36:45

+0

感谢您解释不同的约翰内斯。非常感激。 +1 – 2009-10-23 10:41:18

结构是一个值类型,但类是一个引用类型。这就是为什么它编译时,这是一个类别,但不能当它是一个结构

查看更多:http://www.albahari.com/valuevsreftypes.aspx

一种语法我喜欢@亨克的解决方案是这样的。

DateTime[] dates = new DateTime[10]; 

foreach(int index in Enumerable.Range(0, dates.Length)) 
{ 
    ref DateTime date = ref dates[index]; 

    // Do stuff with date. 
    // ... 
} 

如果你正在做的工作循环的合理量则不必重复索引处处是对眼睛更容易海事组织。

P.S. DateTime实际上是一个非常糟糕的例子,因为它没有任何你可以设置的属性,但你得到的图片。