• 关于 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
  • 相关阅读:
    es6 --- var const let
    HTTP -- 请求/响应 结构
    点击下载文件
    计算机当前时间
    js -- img 随着鼠标滚轮的变化变化
    vue --- 全局守卫
    vue -- 路由懒加载
    vuex -- 状态管理
    js对数组进行操作
    高性能网站建设
  • 原文地址:https://www.cnblogs.com/xiaoqingshe/p/5646550.html
Copyright © 2020-2023  润新知