程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Effective C#原則9:明白幾個相等運算之間的關系(1)

Effective C#原則9:明白幾個相等運算之間的關系(1)

編輯:關於C語言

明白ReferenceEquals(), static Equals(), instance Equals(), 和運算行 符==之間的關系。

當你創建你自己的類型時(不管是類還是結構),你要 定義類型在什麼情況下是相等的。C#提供了4個不同的方法來斷定兩個對象是否 是相等的:

public static bool ReferenceEquals
 ( object left, object right );
public static bool Equals
 ( object left, object right );
public virtual bool Equals( object right);
public static bool Operator==( MyClass left, MyClass right );

這種語言讓你可以為上面所有的4種方法創建自己的版 本。But just because you can doesn't mean that you should.你或許從 來不用重新定義前面兩個方法。你經常遇到的是創建你自己實例的Equals()方法 ,來為你的類型定義語義;或者你偶而重載運==運算符,但這只是為了考慮值類 型的性能。幸運的是,這4個方法的關系,當你改變其中一個時,會影響到其它 的幾個。是的,須要4個方法來完整的測試對象是否完全相等。但你不用擔心, 你可以簡單的搞定它們。

和C#裡其它大多數復雜元素一樣,這個(對相等 的比較運算)也遵守這樣的一個事實:C#充許你同時創建值類型和引用類型。兩 個引用類型的變量在引用同一個對象時,它們是相等的,就像引用到對象的ID一 樣。兩個值類型的變量在它們的類型和內容都是相同時,它們應該是相等的。這 就是為什麼相等測試要這麼多方法了。

我們先從兩個你可能從來不會修 改的方法開始。Object.ReferenceEquals()在兩個變量引用到同一個對象時返回 true,也就是兩個變量具有相同的對象ID。不管比較的類型是引用類型還是值類 型的,這個方法總是檢測對象ID,而不是對象內容。是的,這就是說當你測試兩 個值類型是否相等時,ReferenceEquals()總會返回false,即使你是比較同一個 值類型對象,它也會返回false。這裡有兩個裝箱,會在原則16中討論。(譯注: 因為參數要求兩個引用對象,所以用兩個值類型來調用該方法,會先使兩個參數 都裝箱,這樣一來,兩個引用 對象自然就不相等了。)

int i = 5;
int j = 5;
if ( Object.ReferenceEquals( i, j ))
  Console.WriteLine( "Never happens." );
else
  Console.WriteLine( "Always happens." );
if ( Object.ReferenceEquals( i, i ))
 Console.WriteLine( "Never happens." );
else
 Console.WriteLine( "Always happens." );

你或許決不會重新定義 Object.ReferenceEquals(),這是因為它已經確實實現了它自己的功能:檢測兩 個變量的對象ID(是否相同)。

第二個可能從來不會重新定義的方法是靜 態的Object.Equals()。這個方法在你不清楚兩個參數的運行類型時什麼時,檢 測它們是否相等。記住:C#裡System.Object是一切內容的最終基類。任何時候 你在比較兩個變量時,它們都是System.Object的實例。因此,在不知道它們的 類型時,而等式的改變又是依懶於類型的,這個方法是怎樣來比較兩個變量是否 相等的呢?答案很簡單:這個方法把比較的職責委交給了其中一個正在比較的類 型。靜態的Object.Equals()方法是像下面這樣實現的:

public static bool Equals( object left, object right )
{
 // Check object identity
 if (left == right )
  return true;
 // both null references handled above
 if ((left == null) || (right == null))
  return false;
 return left.Equals (right);
}

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