C# ==、Equals、ReferenceEquals 区别与联系

时间:2022-04-21 14:16:30

基础知识:参考:cyoooo7博客 区别和认识四个判等函数

==运算符:  

引用类型:默认 ==运算符 是比较引用的地址即内存地址 FCL String 类型因为有字符串驻留机制: string A="a"; string B="a"; 返回为True. 引用类型Equals方法和operator==具有相同的默认行为。

值类型:因为如果你没有为自定义值类型重载operator==的话,就不能写这样的代码“myStruct1 == myStruct2”,否则会得到一个编译错误,原因是值类型没有相等操作符重载的默认实现。

ReferenceEquals:

Object的静态方法。因此不能在继承类中重写该方法。原型是:public static bool ReferenceEquals(object objA, object objB);FCL已经帮我们实现。它就是比较引用指向的内存地址一样。判断值类型的时候需要装箱,肯定返回false.FCL String 类型因为有字符串驻留机制: string A="a"; string B="a"; 返回为True.

Equals:  Object类有2个:一个为虚方法,一个为静态方法

                  public virtual bool Equals(object obj);

                  public static bool Equals(object objA, object objB);

值类型:

重写引用类型的Equals方法以改变其默认的比较方式的一个著名例子是String类。当我们写出“string1.Equals(string2)” 这样的代码时,我们比较的不是string1和string2这两个引用所指向的是否为同一个实例(引用等同性),而是比较string1与 string2所包含的字符序列是否相同(逻辑等同性)。

有些人认为值类型的Equals默认实现就是通过比较两个对象在内存中的位表示,即如果所有的二进制位都相等,则说明这两个对象“等同”。这是不准确的。 因为其实值类型的Equals默认实现是对值类型的每个字段都调用该字段类型的Equals方法,如果所有字段的Equals方法都返回true,则他们 才可能相等。

引用类型:引用类型Equals方法的默认实现来自Object,而值类型的默认实现来自TypeValue

            就算Equals会使用==操作符,使用的也是Object或TypeValue的重载版本。原则上来说,只要我们没有重写一个类的Equals方法,那么它就会 继承其父类的实现,

           而父类是没有机会使用子类型的操作符重载的。同样,只要我们没有在一个类的==操作符重载中调用Equals方法,它是不会自动调用 的。