假设我在创建时将一个对象添加到列表中,它是在列表中创建该对象的副本还是创建新对象,请考虑以下代码:
var obj = new A();
obj.Prop = 10;
var list = new List<A>() { obj };
foreach (var l in list) {
l.Prop = 20;
}
Console.WriteLine(obj.Prop);
控制台会打印出什么内容?
最佳答案
答案是肯定和否定。
该列表将包含引用的副本。所以它会指向内存中的同一个对象。除非您在任何这些变量上分配对不同对象的引用或 null,否则它们将继续指向同一事物。
为了避免这种情况,您通常必须转到 into cloning 。与 Java 不同,它没有框架功能。
有两种情况不需要克隆:
- 内置基元类型
- 内置字符串类型(尽管是引用类型)
内置基元类型将其值复制到内存中的新位置。*
字符串在设计上又是不可变的。对于类来说,这是一种罕见的属性,因为在整个 .NET Framework 中甚至很难找到十几个 Inmutable。但在用户定义的类中,这种情况的可能性更大。
对于自制结构,我们甚至鼓励也将其设为不可变。
*除非 JiT 和编译器优化认为它似乎未得到充分利用,因此可以被删除。
关于C# 列表在添加元素或创建副本后是否保存对元素的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58877619/