.NET中的对象相等

时间:2010-01-21 22:59:48

标签: c# object equality

我觉得这很无知,但是有人能够向我解释为什么会这样吗?

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"); //Outputs 1
    }
}

这对我来说是有道理的,因为我使用指针和所有那些伟大的东西,但我的印象是,使用C#,“b”将保持独立于“a”。

我只是使用了一些非常糟糕的做法吗?也许有人可以指点我解释为什么在C#中会出现这种情况?

感谢。

6 个答案:

答案 0 :(得分:10)

这条线让你感到困惑:

a = b;

您希望b按值复制到a,但事实上,您已将b的引用分配给a

.Net将世界划分为两类:引用类型和值类型(还有委托类型和其他几个,但这是另一个故事)。您定义的任何类都是引用类型,并且有一些重要的事项要记住引用类型:

  • 没有内置的方法来进行深层复制
  • 小心检查平等。 ==用于引用相等(变量引用相同的对象),而.Equals()用于值相等,您可能需要覆盖.Equals()(和GetHashCode( ))为你的类型做到这一点。
  • 赋值只是复制引用(这是你的部分)

答案 1 :(得分:4)

你正在使用指针。对象通过引用引用,除非它们来自ValueType

所以

a = b;

将引用a设置为等于b的引用。

答案 2 :(得分:2)

您需要了解的情况是,实际上有4个感兴趣的实体。

  1. MyClass的实例#1
  2. MyClass的实例#2
  3. MyClass参考a
  4. MyClass参考b
  5. 最初引用a引用实例#1,引用b引用实例#2。这是在你执行第a=b;行之前。在此行之后,两者都引用a和引用b指向实例#1。因此,当您致电b.i时,您实际上是在询问实例#1,i的值是多少。不是实例#2。

答案 3 :(得分:1)

没有指针与没有引用对象不同。在您的情况下,'a'是对MyClass类型的特定对象的引用,以及'b'。当您执行'a = b'时,您正在复制引用,而不是对象,因此'a'指向与'b'相同的对象。

答案 4 :(得分:0)

a和b是引用,因此在行a = b之后,a引用与b相同的对象(并且最初由a指向的对象不再可访问)。因此,当您设置a.i时,您还要更新b引用的对象,因此更改。

答案 5 :(得分:0)

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

在您的情况下,当您使用a(赋值)时,您只需将对象b的指针与对象# printf to a variable (psql_array) replacing single quotes by two single quotes printf -v psql_array "'%s'," "${ARRVAR[@]//\'/\'\'}" # remove the trailing , psql_array=${psql_array%,} # check echo "($psql_array)" # or to have a postgresql varchar[] # escape double quote between double quotes printf -v psql_array "\"%s\"," "${ARRVAR[@]//\"/\\\"}" psql_array=${psql_array%,} echo "{$psql_array}" # or easier printf -v psql_array "'%s'::varchar," "${ARRVAR[@]//\'/\'\'}" echo "ARRAY[${psql_array%,}]" 的指针相关联。在此操作之后,对象上的每个交互都将反映给其他人,因为他们只是指向同一个事物。

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