在C#中,如何知道赋值运算符(=)何时复制值或内存地址(引用)?

时间:2014-05-29 15:00:53

标签: c#

例如,在此代码运行后,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);

3 个答案:

答案 0 :(得分:4)

=运算符按值复制struct类型,并按引用复制class类型。

C#不允许覆盖=运算符,可以在C ++中完成。

假设您来自C ++的观点,请考虑在C ++中,内存的值/引用语义由类型的用户决定,而在C#中,它是决定类型的设计者。

因此,假设SomeClassclass顾名思义,当您的示例代码完成时,list2将包含sc并为{{1}创建匿名实例无法访问,将被垃圾收集。

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

答案 1 :(得分:3)

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

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

  • BOOL
  • 字节
  • 小数
  • 枚举
  • INT
  • 为sbyte
  • 结构
  • UINT
  • ULONG
  • USHORT

关于=运营商(根据MSDN):

  

赋值运算符(=)将其右侧操作数的值存储在由其左侧操作数表示的存储位置,属性或索引器中,并将该值作为结果返回。操作数必须是相同的类型(或者右操作数必须可以隐式转换为左操作数的类型)。

答案 2 :(得分:0)

如果我在那里得到了正确的类和结构,播种两类将意味着,如果你有

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

如果你改变list1,list2将改为,list2指向同一个类。

但是如果你使用击中它不会因为它们被取消并且不指向同一个地方而变形。