关于 warning CS0659:“***”重写Object.Equals(object o)但不重写Object.GetHashCode()

对象相等性和同一性

  • System.Object 类型提供了以下方法,
  •  1 namespace System
     2 {
     3     //
     4     // 摘要:
     5     //     支持 .NET Framework 类层次结构中的所有类,并为派生类提供低级别服务。这是 .NET Framework 中所有类的最终基类;它是类型层次结构的根。
     6     [ClassInterface(ClassInterfaceType.AutoDual)]
     7     [ComVisible(true)]
     8     public class Object
     9     {
    10         //
    11         // 摘要:
    12         //     初始化 System.Object 类的新实例。
    13         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
    14         public Object();
    15
    16         //
    17         // 摘要:
    18         //     允许对象在“垃圾回收”回收之前尝试释放资源并执行其他清理操作。
    19         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    20         ~Object();
    21
    22         //
    23         // 摘要:
    24         //     确定指定的对象实例是否被视为相等。
    25         //
    26         // 参数:
    27         //   objA:
    28         //     要比较的第一个对象。
    29         //
    30         //   objB:
    31         //     要比较的第二个对象。
    32         //
    33         // 返回结果:
    34         //     如果认为对象相等,则为 true;否则为 false。如果 objA 和 objB 都为 null,则方法返回 true。
    35         [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    36         public static bool Equals(Object objA, Object objB);
    37         //
    38         // 摘要:
    39         //     确定指定的 System.Object 实例是否是相同的实例。
    40         //
    41         // 参数:
    42         //   objA:
    43         //     要比较的第一个对象。
    44         //
    45         //   objB:
    46         //     要比较的第二个对象。
    47         //
    48         // 返回结果:
    49         //     如果 objA 是与 objB 相同的实例,或如果两者均为 null,则为 true;否则,为 false。
    50         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    51         [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    52         public static bool ReferenceEquals(Object objA, Object objB);
    53         //
    54         // 摘要:
    55         //     确定指定的对象是否等于当前对象。
    56         //
    57         // 参数:
    58         //   obj:
    59         //     要与当前对象进行比较的对象。
    60         //
    61         // 返回结果:
    62         //     如果指定的对象等于当前对象,则为 true;否则为 false。
    63         [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    64         public virtual bool Equals(Object obj);
    65         //
    66         // 摘要:
    67         //     作为默认哈希函数。
    68         //
    69         // 返回结果:
    70         //     当前对象的哈希代码。
    71         [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    72         public virtual int GetHashCode();
    73         //
    74         // 摘要:
    75         //     获取当前实例的 System.Type。
    76         //
    77         // 返回结果:
    78         //     当前实例的准确运行时类型。
    79         [SecuritySafeCritical]
    80         public Type GetType();
    81         //
    82         // 摘要:
    83         //     返回表示当前对象的字符串。
    84         //
    85         // 返回结果:
    86         //     表示当前对象的字符串。
    87         public virtual string ToString();
    88         //
    89         // 摘要:
    90         //     创建当前 System.Object 的浅表副本。
    91         //
    92         // 返回结果:
    93         //     当前 System.Object 的浅表副本。
    94         [SecuritySafeCritical]
    95         protected Object MemberwiseClone();
    96     }
    97 }

    Syste.Object

  • 其中提供了名为Equals的虚方法,它的作用是在两个对象相等的前提下返回true.
  • Equals方法初实现

    看起来似乎是合理的实现,但问题是如果实参引用不同的对象,Equals就不能判断对象是否包含相同的值,就会判定为False.对于Object的Equals的默认实现,它实现的是同一性,而非相等性。

  • 针对以下问题,1)obj实参是否为null,2)this和obj实参是否是引用同一个对象,3)this和obj实参是否引用不同类型的对象,实现Object的Equals方法。
  •  1  public class Object
     2     {
     3         public virtual Boolean Equals(Object obj)
     4         {
     5             if (obj == null)
     6                 return false;
     7             if (this.GetType() != obj.GetType())
     8                 return false;
     9
    10             return true; ;
    11         }
    12     }

    Equals方法

  • 一个类型重写Equals方法时,重写的方法应调用基类的Equals实现(除非这个基类就是Object).另外一个类型能重写Object的Equals方法,所以不能在调用这个Equals方法来测试同一性。Object提供了一个静态方法ReferenceEquals,其原型如下:
  • 1  public Boolean ReferenceEquals(Object objA, Object objB)
    2     {
    3         return (objA == objB);
    4     }

    ReferenceEquals

    如果想检查同一性(看两个引用是否指向同一个对象),那么务必调用ReferenceEquals,而不应使用C#的==操作符(除非先把两个操作数都转型为Object)

  • ValueType的Equals方法使用反射技术,由于CLR的反射机制较慢,所以在定义自己的值类型时,应该重写Equals方法,提供自己的实现,以便在用类型的实例进行值的相等性比较时提高性能。当然,在自己的视线中,不要调用base.Equals。
  • 定义自己的类型时,如果决定重写Equals,必须确定它符合相等性的4个特征。
  • 1)Equals必须是自反的。
  • 2)Equals必须是对称的。
  • 3)Equals必须是可传递的。
  • 4)Equals必须是一致的。
  • 重写Equals方法,还要:
  • 让类型实现System.IEquatable<T>接口的Equals方法。这个泛型接口允许你定义一个类型安全的Equals方法。
  • 重载==和!=操作符方法 通常应事先这些操作符方法,在内部调用类型安全的Equals方法.

除此之外,假如以后出于排序的目的而比较类型的实例,那么类型华英实现System.IComparable的CompareTo方法和System.IComparable<T>的CompareTo方法。

对象哈希吗

System.Object提供了虚方法GetHashCode,它能获取任意对象的Int32哈希吗。

  • 如果定义的一个类型重写了Equals方法,那么还应重写GetHashCode()方法。如果定义的类型在重写Equals的同时没有重写GetHashCode(),Microsoft的C#编译器会报告一条警告消息,例如以下类型,会显示警告消息:warning CS0659:“Program”重写Object.Equals(object o)但不重写Object.HetHashCode().
  • 重写Equals

    之所以要同时定义GetHashCode,是因为在System.Collections.Hashtable类型、System.Collections.Generic.Dictionary类型以及其他一些集合的实现中,要求两个对象为了相等,必须具有相同的哈希吗,所以,如果重写了Equals,那么还应重写GetHashCode,确保相等性算法和对象哈希吗算法是一致的。

  • 1 internal sealed class Point
    2     {
    3         private Int32 m_x, m_y;
    4         public override int GetHashCode()
    5         {
    6             return m_x ^ m_y;
    7         }
    8     }

    GetHashCode

时间: 2024-08-02 08:06:28

关于 warning CS0659:“***”重写Object.Equals(object o)但不重写Object.GetHashCode()的相关文章

Object.equals() 方法

Object.equals() 方法: 1 public class EqualsTest1 { 2 public static void main(String[] args) { 3 //Cat c1 = new Cat(); 4 //Cat c2 = new Cat(); 5 //System.out.println(c1 == c2);//result:false 6 Cat c3 = new Cat(1,2,3); 7 Cat c4 = new Cat(1,2,3);//在重写equa

讲的很详细的一篇关于object equals() &amp; hashCode() 的文章

转: 讲的很详细的一篇关于object equals() & hashCode() 的文章 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现. 为何Object类需要这样一个方法?它有什么作用呢?今天我们就来具体探讨一下hashCode方

你不知道的东西! c# == 等于运算符 和 Object.Equals()

最近在看 高级点的程序员必看的     CLR via C#    书中说解释了 Object.Equals()  方法的实现, 其中具体的实现用的是 == 运算符 ! 以前就对 == 运算符 的具体实现  产生过疑惑 . 它到底对比的什么? 今天刚好手头的东西弄完了,而且还得强制加班中 !  所以就那今天的加班时间 来认真 来看一下 == 运算符 ! 最早对于 == 和 Object.Equals()  的了解是来源于 很早以前的一次面试 上面的面试题就有这个问题, 非常遗憾是 当时我水平有限

java中Object.equals()简单用法

/* equals()方法默认的比较两个对象的引用! */ class Child { int num; public Child(int x){ num = x; } //人文的抛出运行时异常的好处是:可以自定义错误信息! /*public boolean equals(Object o) throws ClassCastException{ if(!(o instanceof Child)) throw new ClassCastException("中文提示:类型错误"); Ch

【Java编码准则】の #11不要使用Object.equals()来比较密钥值

java.lang.Object.equals()函数默认情况下是不能用来比较组合对象的,例如密钥值.很多Key类没有覆写equals()函数,因此,组合对象的比较必须单独比较里面的各个类型以保证正确性. [不符合安全要求的代码示例] 下面的代码使用equals()函数比较两个key值,key值即使具有相同的取值也可能会返回不相等,导致结果出错. private static boolean keysEqual(Key key1, Key key2) { if (key1.equals(key2

object.Equals与object.ReferenceEquals方法

object.Equals方法表达的是语义判等,不一定是引用判等. object.ReferenceEquals方法是肯定是引用判等. 怎么实现一个对象的值语义的 Equals方法?实验. MyClass bool Equals(MyClass other) { // 1. other==null? // 2. 实际type是否相等 // 3. 简单类型的字段是否相等.调用引用类型的字段的Equals方法. } Notes: MyClass对象因的字段,以及引用字段又引用的字段,可能结果是递归遍

【Java编码准则】の #11不要使用Object.equals()来比較密钥值

java.lang.Object.equals()函数默认情况下是不能用来比較组合对象的,比如密钥值.非常多Key类没有覆写equals()函数,因此,组合对象的比較必须单独比較里面的各个类型以保证正确性. [不符合安全要求的代码演示样例] 以下的代码使用equals()函数比較两个key值,key值即使具有同样的取值也可能会返回不相等,导致结果出错. private static boolean keysEqual(Key key1, Key key2) { if (key1.equals(k

浅析Object基类提供的Virtual Object.Equals, Static Object.Equals and Reference.Equals等三个方法

当我们去查看object.cs源代码文件的时候,会发现object基类提供了三种判断相等性的方法.弄清楚每种方法存在的原因,也就是具体解决了什么问题,对我们理解.net判断对象相等性的逻辑很有帮助,下面让我们分别来看看吧! 1.Virtual Object.Equals()方法 实际上.net中提供了几种比较相等性(equality)的方法,但是最基础的方法就数object类中定义的virtual Object.Equals()了.下面让我们以一个customer类来看看该方法的实际运作. st

java 覆写Object.equals() 方法

1 //覆写Object.equals 2 class Demo { 3 private String name; 4 private int age; 5 public Demo(String name,int age) { 6 this.name=name; 7 this.age=age; 8 } 9 public String toString() { 10 return this.name+this.age; 11 } 12 public boolean equals(Object ob