在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);
=
操作符按值复制struct
类型,按引用复制class
类型。
c#不允许覆盖=
操作符,而在c++中可以这样做。
假设你是从c++的角度出发,考虑在c++中内存的值/引用语义是由类型的用户决定的,而在c#中是由类型的设计者决定的。
因此,假设SomeClass
顾名思义是class
,当示例代码完成时,list2
将包含sc
,并且为list2
创建的匿名实例不可达,将被垃圾收集。
list1.RemoveAt[0]
的语法也不正确。您必须使用()
而不是[]
应用于值类型的=
运算符将把一个值复制到变量中。对于所有其他(引用类型),它将"复制"内存地址。
值类型的完整列表(源MSDN):
- bool <
- 字节/gh>
- 字符 小数点
- 双 enum >
- int
- sbyte
- 短gh>
- struct
- 使用uint
- ulong
- ushort
关于=
操作符(根据MSDN):
赋值操作符(=)将右操作数的值存储在左操作数表示的存储位置、属性或索引中,并返回该值作为操作结果。操作数必须具有相同的类型(或者右操作数必须隐式地转换为左操作数的类型)。
如果我把这个写在这里类和结构将依赖于两个类这意味着如果你有
List<SomeClass> list1 = new List<SomeClass>();
List<SomeClass> list2 = new List<SomeClass>();
如果你改变list1, list2也会改变,list2指向同一个类