談談C#的相等性(1)

相等性是個很重要的觀念,因為在不同的程式語言,相等性往往代表不同的涵義。

相等性就跟開水白菜一樣,外表看起來簡單,其實內容博大精深。

C#有哪些方法可以判斷相等性?

  1. 運算子 Operator== 和 Operator!=
  2. 萬物之母 System.Object 上的 virtual 方法
  3. 萬物之母System.Object上的 static 方法

在探討這三種方法的差別以前,我們先往後退一步,給相等性兩個不同的定義。

兩種相等性

Reference Equality

第一種是參考相等,代表兩個物件參考記憶體內相同的底層物件。

System.Object.ReferenceEquals 用於判定兩物件是否參考相等。

一個重要的觀念是,參考相等只有對Reference Type物件有意義,對於Value Type物件而言,assignment會複製其值,底層依舊是兩個相同內容的不同物件,所以Reference Equals會永遠回傳false。

將value type傳入System.Object.ReferenceEquals時,會發生Boxing。傳入的兩個整數1會各自被Boxing成object,放置在heap上進行reference equality比較,結果為false。

另外null也是一種reference,代表沒有參考到任何物件。是所有reference type物件的預設值。所以

Value Equality

Value Equality概念很簡單,兩個物件包含的值內容相等就是為相等。
對於那些primitive value type,像是int, bool等,可以直接用 operator == 判定相等即可。

但對於比較複雜的型別,如struct, class等,直觀的想法是所有的field都包含相同的值,視為value equality。但並不保證一定如此。實際情況還是要看struct, class對於Value Equality的定義。

另外特別注意,浮點數的Value Equality可能會因為精度問題而出事。就不在此贅述了。幾乎所有的語言都有這樣的問題。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *