.NET 中的对象相等性

3
我感到很无知,但有人能解释一下为什么会发生这种情况吗?
class MyClass{ public int i {get; set; } }
class Program
{
    static void Main(string[] args)
    {
        MyClass a = new MyClass();
        MyClass b = new MyClass();
b.i = 2; a = b; a.i = 1;
Console.Write(b.i + "\n"); //输出1 } }
如果我使用指针和所有伟大的东西,这对我来说是有道理的,但我认为在C#中,“b”将保持独立于“a”。
我只是在使用一些非常糟糕的做法吗?也许有人可以指点我为什么在C#中会出现这种情况?
谢谢。
6个回答

10

你感到困惑的是这一行:

a = b;
你期望变量 a 能够通过值复制变量 b,但实际上你只是将变量 a 指向了变量 b 所指向的对象。
在 .NET 中,世界被分成两类:引用类型和值类型(还有委托类型和其他一些类型,但那是另一个故事)。 你定义的任何类都是引用类型,对于引用类型需要记住几点重要的事情:
  • 没有内置的方法可以进行深拷贝
  • 检查相等时要小心。== 用于引用相等性(变量是否引用相同的对象),而 .Equals() 用于值相等性,你可能需要为自己的类型重写 .Equals()(和 GetHashCode())方法来正确比较。
  • 赋值仅仅是复制了引用(这就是让你犯错的地方)

谢谢,我感觉很愚蠢,但是我很感激你的解释。 - KarlHungus

4

您正在以某种方式使用指针。除非它们是ValueType的子类,否则对象将通过引用进行引用。

因此,

a = b;

设置引用a等于引用b

2
你需要理解的是,这个场景中实际上有4个相关实体。
  1. MyClass 的实例 #1
  2. MyClass 的实例 #2
  3. MyClass 引用 a
  4. MyClass 引用 b
最初,引用 a 指向实例 #1,引用 b 指向实例 #2。直到执行了 a=b; 这行代码后,引用 a 和引用 b 都指向实例 #1。所以当你调用 b.i 时,实际上是在问实例 #1 i 的值是多少,而不是实例 #2。

1
没有指针并不意味着没有对对象的引用。在你的情况下,'a' 是对 MyClass 类型的一个特定对象的引用,'b' 也是如此。当你执行 'a = b' 时,你复制的是引用,而不是对象,所以 'a' 指向 与 'b' 相同的对象。

0

a和b是引用,所以在a = b这一行之后,a引用与b相同的对象(原本由a指向的对象不再可达)。因此,当您设置a.i时,您也会更新b所引用的对象,因此发生了变化。


0

.NET 中的每个类都是引用类型。这意味着当您创建一个新实例时,它指向内存中的一个引用而不是保留其值。

在您的情况下,当您使用 = 运算符(赋值)时,您只是将对象 a 的指针关联到对象 b 的指针上。在此操作之后,对对象的每个交互都将反映到另一个对象上,因为它们只是指向同一物体。

如果您需要复制对象,则必须自己编写代码。但这是另一回事。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接