2015年9月12日 星期六

C# equals

之前考試遇到的題目,覺得==、equlas這兩者到底預設使用什麼比較蠻重要的觀念,所以還是來記錄一下。

class Test
{
public int field = 10;
}
Test test1 = new Test();
Test test2 = new Test();

  1. test1 == test2  => false
    因為Reference type的==,根據預設會藉由判斷兩個參考是否表示相同的物件,以測試參考是否相等,所以代表預設應該是使用類似object.ReferenceEquals來比較兩者的reference是否相等。
  2. test1.Equals(test2) => false
    同1,預設也是檢查參考
  3. object.ReferenceEquals(test1, test2) => false

知道reference的==和equlas預設是使用什麼,接下來只要分別你的data type是value type還是reference type就好。 而大家一般搞混string的是它其實是reference type,只是它implements ==和Equals function會比較字串的值。 基本上上面就解決大部分的問題,後來看到這篇所提到的boxing,也是相當需要注意的。Boxing概念主要就是把數值轉成object,所以就看轉成的object,因為轉成object就是reference type了,也因為==必須標明實際的data type,所以如果是object==object,則當然就是預設檢查reference。但注意如果Unboxing的話==則自然就變成value==value了。

最後唯一的例外一樣是同一篇提到的,字串的常數,照理說字串是reference,宣告兩個相同值的字串常數用成object type,檢查==應該就是檢查reference,可是CLR存在著一種機制,當它初始化時,它會創建一個內部hash,其中key是我們所要存放的字串,而value是誰引用。當定義一個新的string 時,系統會檢查是否有相同的。如果找不到,就建立一個新的,如果找到就直接引用。所以object type兩個字串的常數,reference會是相同的,真是麻煩………..