關於 warning CS0659:“***”重寫Object.Equals(object o)但不重寫Object.GetHashCode()

來源:互聯網
上載者:User

標籤:

對象相等性和同一性
  • 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 Point2     {3         private Int32 m_x, m_y;4         public override int GetHashCode()5         {6             return m_x ^ m_y;7         }8     }
    GetHashCode

     

關於 warning CS0659:“***”重寫Object.Equals(object o)但不重寫Object.GetHashCode()

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.