之前考試遇到的題目,覺得==、equlas這兩者到底預設使用什麼比較蠻重要的觀念,所以還是來記錄一下。
class Test { public int field = 10; } Test test1 = new Test(); Test test2 = new Test();
- test1 == test2 => false
因為Reference type的==,根據預設會藉由判斷兩個參考是否表示相同的物件,以測試參考是否相等,所以代表預設應該是使用類似object.ReferenceEquals來比較兩者的reference是否相等。
- test1.Equals(test2) => false
同1,預設也是檢查參考
- 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會是相同的,真是麻煩………..