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

2024-04-22

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

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

代码中的 foreach 循环无法编译,而注释的 for 循环工作正常。错误信息:

无法修改“item”的成员,因为它是“foreach 迭代变量”

这是为什么?


因为 foreach 使用枚举器,而枚举器不能改变底层集合,但是can但是,更改任何对象引用者集合中的一个对象。这就是值和引用类型语义发挥作用的地方。

在引用类型(即类)上,集合存储的所有内容都是对对象的引用。因此,它实际上从未接触过对象的任何成员,也不会关心它们。对对象的更改不会影响集合。

另一方面,值类型将其整个结构存储在集合中。在不更改集合并使枚举器无效的情况下,您无法触摸其成员。

此外,枚举器返回a copy的收藏价值。在 ref 类型中,这没有任何意义。引用的副本将是相同的引用,并且您可以以任何您想要的方式更改引用的对象,并且更改会超出范围。另一方面,在值类型上,意味着您获得的只是对象的副本,因此该副本上的任何更改都永远不会传播。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐