在c#中,我如何知道赋值操作符(=)何时会复制值或内存地址(引用)?

本文关键字:何时会 复制 内存 引用 地址 赋值操作符 何知道 | 更新日期: 2023-09-27 18:05:41

例如,在这段代码运行之后,list2包含什么,我如何对此有信心?

List<SomeClass> list1 = new List<SomeClass>();
List<SomeClass> list2 = new List<SomeClass>();
SomeClass sc = new SomeClass(); // assume assignment operator (=) 
                                // is defined for this class
list1.Add(sc);
list2.Add(new SomeClass());
list2[0] = list1[0];
list1.RemoveAt(0);

在c#中,我如何知道赋值操作符(=)何时会复制值或内存地址(引用)?

=操作符按值复制struct类型,按引用复制class类型。

c#不允许覆盖=操作符,而在c++中可以这样做。

假设你是从c++的角度出发,考虑在c++中内存的值/引用语义是由类型的用户决定的,而在c#中是由类型的设计者决定的。

因此,假设SomeClass顾名思义是class,当示例代码完成时,list2将包含sc,并且为list2创建的匿名实例不可达,将被垃圾收集。

list1.RemoveAt[0]的语法也不正确。您必须使用()而不是[]

应用于值类型的=运算符将把一个值复制到变量中。对于所有其他(引用类型),它将"复制"内存地址。

值类型的完整列表(源MSDN):

  • bool
  • <
  • 字节/gh>
  • 字符
  • 小数点
  • enum >
  • int
  • sbyte
  • struct
  • 使用uint
  • ulong
  • ushort

关于=操作符(根据MSDN):

赋值操作符(=)将右操作数的值存储在左操作数表示的存储位置、属性或索引中,并返回该值作为操作结果。操作数必须具有相同的类型(或者右操作数必须隐式地转换为左操作数的类型)。

如果我把这个写在这里类和结构将依赖于两个类这意味着如果你有

List<SomeClass> list1 = new List<SomeClass>();
List<SomeClass> list2 = new List<SomeClass>();

如果你改变list1, list2也会改变,list2指向同一个类