程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#中的類型相等與恆等(Equality & Identity)

C#中的類型相等與恆等(Equality & Identity)

編輯:關於C#

CLR提供了可以區分類型的Equality 和Identity能力。

l Equality:如果兩個對象是相同的類型,並且它們各自帶有相同和等值的屬性。(They are instances of the same type and if each of the fields in one object matches the values of the fields in the other object)

Equality必須滿足三個必要條件:reflexive, symmetrics, and transitive

reflexive: 自身相等,及a==a 是永遠成立的;

symmetrics: 對象性,及a==b成立那麼b==a 也成立;

transitive: 傳遞性,及a==b, b==c成立那麼a==c 也成立。

l Identity:兩個對象必須相等(意味著他們共享同一塊內存區域)(The two objects have the same values.– Two objects are identical if they share an address in memory)

CLR提供了至少四種方法來判斷兩個對象的等價性:

1.Public static bool ReferenceEquals(object left, object right);

2.Public static bool Equals(object left, object right);

3.Public virtual bool Equals(object right);

4.Public static bool operator==(MyClass left, MyClass right);

ReferenceEquals方法總是用來判斷兩個對象的Identity的,不管是針對值類型還是引用類型。所以針對值類型,調用該方法總是會返回false,因為值類型作為這個方法的參數時會進行裝箱操作。

靜態的Equals方法提供了判斷兩個對象的Equality能力,在其實現的內部,調用了上述第三個虛擬的Equals方法。和ReferenceEquals一樣,它們已經具備從底層判斷兩個對象的能力,我們從來不會覆寫這兩個方法。

實例Equals方法也是用來區分兩個對象的Equality的。

l 對於引用類型的對象,它和ReferenceEquals方法幾乎是一樣的。(因為判斷兩個引用類型是否的Equality往往從Identity上就可以區分)

l 而值類型的對象,我們不僅要判斷他們具有相同的對象類型,還要判斷他們的值相等。值類型從System.ValueType繼承而來,ValueType已經重寫了Object.Equals()方法,本來已經可以用來滿足這些要求的。但是ValueType.Equals()方法不是很有效,因為它必須要通過反射,在不知道具體的派生類型中,完成對它們所含有成員變量的值的比較。因此,建議在我們實現一個值類型的數據結構時,同時重寫ValueType.Equals()方法。

l 然而我們再回頭看看引用類型,有時兩個引用類型的對象往往被用來進行類似值類型的比較,比如:String類型,它雖然是引用類型,但它也重寫了Equals方法,因為我們拿它來判斷兩個string是否相同(Equality),實際是希望判斷它們是否具有相同的內容,這是一個value semantics。因此,我們建議在考慮實現一個用作值語義環境下的引用類型時候,也重寫基類的Object.Equals()方法。

注:請參考MDSN或其它相關文檔,如何實現Equals方法的重寫。

上面的圖示給了很好的例子來區分Equals和ReferenceEquals方法,被用來做Equility和Identity判斷的區別。

==運算符是可由類重載的運算符,它也是用來判斷恆等的。

對於未重載==的引用類型,會比較兩個引用類型是否引用同一個對象。這跟引用類型的Equals()方法是一樣的。

對於未重載==的值類型,該運算符會比較這兩個值是否"按位"相等,即是否這兩個值中的每個字段都相等。和Equals方法一樣,推薦在自定義值類型中,也要重載==運算符,因為也存在反射在效率上的影響。

==運算符和Equals方法的區別在於多態表現上。Equals方法是重寫,而==運算符是被重載。這意味著除非編譯器知道調用具體的重載版本,否則它只是調用未重載的==版本。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved