從《Microsoft.net框架程序設(shè)計》一書中,看到Equals的實現(xiàn)基本分為如下三類(順序有所調(diào)整):(1)引用類型,從MyRefType到Object的繼承鏈上(基類、基類的基類、...),有類覆蓋了Object的Equals方法實現(xiàn);(2)引用類型,從MyRefType到Object的繼承鏈上(基類、基類的基類、...),均沒有類覆蓋Object的Equals方法實現(xiàn);(3)值類型的Equals方法實現(xiàn)。分法相當(dāng)科學(xué),不過我看了其中的代碼實現(xiàn),針對第二種實現(xiàn)有一些自己的疑惑和想法。為了沒有看過該書的同仁們更好地理解,我將書中的實現(xiàn)貼在此文中。先看書中第一種,(1)引用類型,從MyRefType到Object的繼承鏈上(基類、基類的基類、...),有類覆蓋了Object的Equals方法的實現(xiàn):
其中用到了Object的Equals方法,將原代碼貼出來
在這種實現(xiàn)中,個人認為Equals方法是沒有問題的,首先調(diào)用
比較了基類的部分,然后就比較自己的部分就OK了。再看書中的第二種,2)引用類型,從MyRefType到Object的繼承鏈上(基類、基類的基類、...),均沒有類覆蓋Object的Equals方法的實現(xiàn);
我們可以發(fā)現(xiàn),同第一種實現(xiàn)的差別在于沒有了如下代碼段:
為什么不能加這一段呢?因為在這種實現(xiàn)環(huán)境下,我們設(shè)定了前提:從MyRefType到Object的繼承鏈上,均沒有類覆蓋Object的Equals方法。所以如果加了上面這段代碼,那實際調(diào)用的是Object類的實例方法Equals
這樣,如果this和obj不指向同一個對象,則這個base.Equals(obj)肯定返回false,于是Equals也返回false,而在this和obj指向同一個對象,Equals返回true,這樣不就是Object的Equals()實現(xiàn)嗎?既然如此,何苦自己重新這個函數(shù)呢?既然重寫了,那肯定有不一樣的行為,于是下面的代碼段加入不得。
到這里,我們也可以理解。不過問題是,沒有加入這段代碼,從“(2)引用類型,從MyRefType到Object的繼承鏈上(基類、基類的基類、...),均沒有類覆蓋Object的Equals方法的實現(xiàn)”中,我們好像找不到比較基類成員的影子。不比較基類成員,是否合理呢?看下面例子,如果兩個Derived對象,無需比較Base部分的成員變量,那么下面的寫法是正確的,此時該程序打印出的結(jié)果為True。
但是有時邏輯要求,兩個Derived對象需要比較Base部分的成員變量,那上面的寫法就是錯誤的,此時應(yīng)該修改為如下的代碼,該程序打印出的結(jié)果為False。
再看第三種實現(xiàn):(3)值類型的Equals方法實現(xiàn)。書中代碼如下:
這種實現(xiàn)方法,如果不存在其它類對MyValType的隱式類型轉(zhuǎn)換,是沒有問題的,如果存在隱式類型轉(zhuǎn)換,那代碼中的強類型Equals()方法(從第16行開始)就可能存在問題了。試想想,兩種不同類型的實例,我們有多少場合會認為他們Equals呢?根據(jù)邏輯來定,一般不會認為它們相同。為了說明存在的這個問題,請看如下代碼:
上面代碼中,一般從常理來說,我們不會認為myValue1和myValue2相等,因為他們是不同類型的實例(myValue1屬于MyValType類型,myValue2屬于MyValType2類型)。但是實際輸出了結(jié)果True。個中原因在于定義了一個從MyValType2到MyValType的隱式轉(zhuǎn)換:
于是在運行語句myValue1.Equals(myValue2)時,會先將myValue2轉(zhuǎn)換為一個MyValType類型的臨時變量,然后用MyValue1和這個臨時變量比較,此時調(diào)用強類型的比較函數(shù),因為MyValType和MyValType2這兩個類型內(nèi)部結(jié)構(gòu)一樣,且兩變量的內(nèi)部field的值相同,所以返回True。上面例子說明 ,如果不能確保沒有其他類型到該類型的隱式轉(zhuǎn)換,那萬無一失的辦法就是不實現(xiàn)強類型的Equals。調(diào)用默認的Equals方法或者實現(xiàn)參數(shù)為Object的Equals方法,雖然效率可能差一點,但是可靠。當(dāng)然,如果可以確認沒有其他類型到該類型的隱式轉(zhuǎn)換,那實現(xiàn)強類型的Equals方法還是可以帶來效率的提升。(相同描述可參見《.net框架程序設(shè)計》)。關(guān)于Equals()方法的實現(xiàn),基本上也就到此結(jié)束了。如果各位有什么好的心得,歡迎積極探討。
posted on 2009-04-26 23:33 五味雜陳 閱讀(1534) 評論(0) 編輯 收藏 引用 所屬分類: .NET
Powered by: C++博客 Copyright © 五味雜陳