C#中==与Equals区别

时间:2021-12-06 16:11:43

C#中的相等有两种类型:引用相等(ReferenceEquals)值相等(Equals)。值相等就是说两个对象包含相同的值。而引用相等则比较的是两个对象的引用是否是同一个对象。也就是说,如果ReferenceEqualsTrue,则Equals必然为True,反过来就不一定了。

这样的话可以看出来,ReferenceEquals我们没有比较去管他什么,系统自动解决,object类实现的静态RefrenceEquals函数就够了。而对于自定义的类型的话,如果想要实现判断值相等,是需要重写Equals函数的。

我们可以看一下string和自定义类的对比:

string strA = "Hello";

string strB = string.Copy(strA);

Console.WriteLine(strA == strB);         //True

Console.WriteLine(strA.Equals(strB));    //True

Console.WriteLine(object.Equals(strA, strB));    //True

Console.WriteLine(object.ReferenceEquals(strA, strB));       //False

class MyClass

{

    public int value = 1;

}

...

MyClass oA = new MyClass();

MyClass oB = new MyClass();

Console.WriteLine(oA == oB);   //False

Console.WriteLine(oA.Equals(oB));  //False

Console.WriteLine(object.Equals(oA, oB));  //False

Console.WriteLine(object.ReferenceEquals(oA, oB)); //False

先不考虑==号,看几个Equals的表现,Equals是要实现值相等比较的效果的,.net 在实现string的时候就重写了Equals(object) ,并添加重载函数Equals(string) ,因此两个比较才会返回True。而不实现这两个函数的后果就是都返回False,无法符合Equals函数应有的作用。

由此看来,对于之前我的需求:比较两个自定义类的内容是否相同,还是应该重写Equals(Object),并建议重载对自己的类的实现Equals(MyClass)

而对于==运算符的解释为:通过过判断两个引用是否指示同一对象来测试是否相等。也就是引用相等了,可对于上面对string的测试,RefrenceEqualsFalse时,==却返回的True,这是因为还有这么一条:当类型不可变(即实例中包含的数据不可更改)时,通过重载运算符== 来比较值是否相等而不是比较引用是否相等可能会很有用

我们大部分情况下写的自定义类都是可变的,所以一般用不到也不应该对==进行重载