Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
433 views
in Technique[技术] by (71.8m points)

In C#, why can't I modify the member of a value type instance in a foreach loop?

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();
    }
}

The foreach loop in the code doesn't compile while the commented for loop works fine. The error message:

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

Why is that?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...