首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Effective C# 原則 9:釐清多種相等運算之關係(二)

     編輯:關於C語言

靜態 Equals 與執行個體 Equals 的關係

前一篇介紹的兩個方法——運算子 ==() 和執行個體 Equals()——尚未討論。我將詳細說明,但先完成靜態 Equals() 的探討。請理解:靜態 Equals() 使用左側參數執行個體的 Equals() 方法判斷兩物件是否相等。

為何不需重新定義靜態 Equals 與 ReferenceEquals

同 ReferenceEquals(),你或許永遠不需重新定義靜態 Object.Equals(),因它已確實完成任務:在不知兩物件確切型別時判斷是否相同。靜態 Equals() 將比較委派給左側參數執行個體的 Equals(),以此處理另一型別。

數學相等性質:自反性、對稱性、傳遞性

重新定義方法時,實作必須符合其他程式設計師預期的數學性質:

  • 自反性:物件等於自己,a==a 恆為 true。
  • 對稱性:a==b 為真,則 b==a 必為真。
  • 傳遞性:a==b 且 b==c 為真,則 a==c 必為真。

執行個體 Object.Equals() 何時該覆寫

當預設行為與你的型別不一致時,應建立自己的執行個體版本。Object.Equals() 使用物件 ID 判斷兩變數是否相等,預設行為同 Object.ReferenceEquals()。但實值型別不同:System.ValueType 未覆寫 Object.Equals()(它是所有 struct 的基類)。兩實值型別變數相等,若型別與內容皆相同。ValueType.Equals() 實作此行為,但效率不高:必須在不知衍生型別情況下比較所有成員,意味著需用反射(原則 44 將詳述反射缺點)。

建議:實值型別總是覆寫 Equals()

相等比較是應用程式頻繁呼叫的基礎設施,效能值得重視。大多數情況下,可為任何實值型別覆寫更快的 Equals()。簡單建議:建立實值型別時,總是覆寫 ValueType.Equals()。

參考型別何時覆寫 Equals()

僅當你想改變參考型別定義的 Equals() 語意時。.NET 框架中大量類別使用實值型別語意(比較內容)取代參考型別語意(比較物件 ID)。例如:兩 String 內容相同則相等;兩 DataRowView 參考同一 DataRow 則相等。關鍵在於:若你的型別須遵循實值型別語意(比較內容)而非參考型別語意,應自行覆寫執行個體 Object.Equals()。

標準實作模式

public class Foo
{
    public override bool Equals(object right)
    {
        if (right == null) return false;
        if (object.ReferenceEquals(this, right)) return true;
        if (this.GetType() != right.GetType()) return false;
        return CompareFooMembers(this, right as Foo);
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved