在C#中,我为什么不能修改的值类型实例的成员在foreach循环?

在C#中,我为什么不能修改的值类型实例的成员在foreach循环?

问题描述:

我知道值类型应该是一成不变的,但是这只是一个建议,不是规则,对不对?
那么,为什么我不能做这样的事情:

I know that value types should be immutable, but that's just a suggestion, not a rule, right? So why can't I do something like this:

struct MyStruct
{
    public string Name { get; set; }
}

 public class Program
{
    static void Main(string[] args)
    {
        MyStruct[] array = new MyStruct[] { new MyStruct { Name = "1" }, new MyStruct { Name = "2" } };
        foreach (var item in array)
        {
            item.Name = "3";
        }
        //for (int i = 0; i < array.Length; i++)
        //{
        //    array[i].Name = "3";
        //}

        Console.ReadLine();
    }
}

在code foreach循环,而评论的循环工作正常,没有编译。
这是为什么?

The foreach loop in the code doesn't compile while the commented for loop works fine. Why is that?

由于使用的foreach一个枚举,和枚举器不能改变底层集合,而,但是,更改任何对象的的一个集合中的对象引用。这是值类型和引用类型的语义开始发挥作用。

Because foreach uses an enumerator, and enumerators can't change the underlying collection, but can, however, change any objects referenced by an object in the collection. This is where Value and Reference-type semantics come into play.

在引用类型,即,一类,所有的集合被存储是对一个对象的引用。因此,它从来没有真正触及任何对象的成员,并可能不关心他们。对象的改变不会接触到集合。

On a reference type, that is, a class, all the collection is storing is a reference to an object. As such, it never actually touches any of the object's members, and couldn't care less about them. A change to the object won't touch the collection.

在另一方面,值类型存储集合在其整个结构。你不能碰其成员不改变的收集和枚举无效。

On the other hand, value types store their entire structure in the collection. You can't touch its members without changing the collection and invalidating the enumerator.

此外,枚举器返回的复制的集合中的价值。在一个引用类型,这意味着什么。一个引用的副本将是相同的参考,你可以在你想改变小号preading超出范围的任何方式改变引用的对象。在一个价值型,而另一方面,这意味着你得到的是该对象的副本,从而对所述拷贝将永远不会传播。任何修改

Moreover, the enumerator returns a copy of the value in the collection. In a ref-type, this means nothing. A copy of a reference will be the same reference, and you can change the referenced object in any way you want with the changes spreading out of scope. On a value-type, on the other hand, means all you get is a copy of the object, and thus any changes on said copy will never propagate.