C# list 在添加元素或创建副本后是否保留对该元素的引用?

C# Does list hold a reference to the element after adding it or creates a copy?

假设我在创建时将一个对象添加到列表中,它是在列表中创建该对象的副本还是创建新对象,请考虑以下代码:

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

控制台会打印什么?

does it create a copy of the object in a list or does it create new object

当你谈论引用类型时,对象是同一个对象,只是对其进行引用,如果你以某种方式更改对象的状态,它也会反映在列表中,因为两者都是指向同一个对象。

obj 和列表中添加的项目 new List<A>() { obj }; 都指向相同的内存位置,因为它是引用类型。因此,实际上并没有创建新对象。创建了引用的副本,并且两者都持有对同一引用的引用。

答案是肯定和否。

该列表将包含一份副本 - 但包含参考资料。所以它会指向内存中的同一个对象。除非您在这些变量中的任何一个处分配对不同对象或 null 的引用,否则它们将继续指向同一事物。

为避免这种情况,您通常必须去 into cloning。与 Java 不同,它没有框架功能。

有两种情况不需要克隆:

  1. 内置基元类型
  2. 内置字符串类型(尽管是引用类型)

内置基元类型将其值复制到内存中的新位置。*

字符串在设计上是不可变的。对于 class,这是一个罕见的 属性,因为您甚至很难在整个 .NET Framework 中找到一打 Inmutables。但在用户定义的 classes 中,它更有可能。

对于自制结构,您甚至鼓励也将其设为不可变。

*除非 JiT 和编译器优化认为它似乎没有得到充分利用,因此可以将其删除。