在.net中跃惫,經(jīng)常需要比較兩個對象是否相等(值相等或者地址引用相同)钉嘹,而 .net(C#)中提供的相等判斷有很多種,有時候經(jīng)常搞混淆剖张,比如何時用==?何時用equals()方法揩环?為此搔弄,我決定花一點時間弄清楚這些相等判斷的含義及其用法,在此做個總結(jié)丰滑。
一. 相等判斷的種類
在C#中顾犹,如果需要對兩個對象進行相等判斷。不外乎兩種情況褒墨,判斷兩者的值相等或者判斷兩者的引用地址相同炫刷。一般情況下,我們需要對值類型對象判斷值相等(不清楚值類型和引用類型的可以自行百度)郁妈,對引用類型對象判斷指向地址相同浑玛。在C#中,一共提供了四種方式來進行判斷噩咪,分別如下:
. ==運算符
.對象自身的equals()方法
.object類的靜態(tài)方法equals()
.object類的靜態(tài)方法referenceequals()
二. 方法之間的差異
為了了解上述四種方法之間的差異顾彰,我做了一張表格极阅,如下
在上述表格中,比較了四種方法對不同的對象進行判斷所進行的真實操作涨享。其中筋搏,String類型的對象本來是屬于引用類型的,但是因為它是一種比較特殊的引用類型厕隧,所以此處單獨列出來奔脐。
下面對上述表格進行解釋:
- == 運算符
如果作用于兩個值對象,兩個值類型對象的取值將進行比較吁讨。
int a=1;
int b=1;
a==b;//a與b的取值相等髓迎,因此==的結(jié)果為true
如果作用于兩個引用對象,則兩者進行地址的相等比較挡爵。
ClassTemp a =new ClassTemp(); //假設a為ClassTemp對象的一個實例
ClassTemp b =new ClassTemp(); // b同樣為ClassTemp的一個實例
a==b//a與b均為引用類型勋篓,兩者雖然內(nèi)容相同镶殷,但地址不同驮肉,返回false
如果==作用于兩個String類型對象全释,雖然String類型為引用類型,但因為String類對==運算符和equals()方法進行了override闭翩。因此判斷的結(jié)果還是比較兩個string的內(nèi)容是否相等挣郭。
- equals()方法
object類定義了equals(object)方法這一個虛方法,由于object類為所有類的祖先疗韵,因此實際上每一個對象都包含了equals(objcet)方法兑障。
這個方法的使用很簡單,例如:
int a=1;
int b=1;
a.equals(b);//a與b的取值相等蕉汪,結(jié)果為true
從表格中可以看出流译,equals()方法和==似乎沒有什么區(qū)別。不過者疤,MSDN中強烈建議我們對這個方法進行override來創(chuàng)建自己的“相等判斷”方法福澡。
- object.referenceEquals()和object.Equals()
object 類還定義了兩個靜態(tài)方法equals(object,object)和referenceEquals(object,object)驹马。我們可以也可以利用這兩個方法進行相等比較革砸。
referenceEquals(object,object)是對兩個對象的地址進行比較,如果兩個對象都為值類型糯累,則對兩個對象進行裝箱算利,因為裝箱后得到的地址必然不一樣,因此比較的結(jié)果為false泳姐。
referenceEquals()特別適合下面這種情況使用:當某個類型的equals的方法被override了效拭,其對兩個引用類型的判斷不再是比較地址,而你又想對兩者進行地址判斷,此時使用referenceEquals方法最合適允耿,因為它是靜態(tài)方法借笙,不會被override。
object.equals(object)靜態(tài)方法的稍微復雜一點较锡,大致判斷邏輯如下:
如果你利用此方法對A,B進行判斷盗痒,即object.equals(A,B)
1蚂蕴,首先調(diào)用object.referenceEquals()對兩者地址進行相等判斷,如果相同俯邓,則返回true骡楼。
2,上述不成立稽鞭,則對兩者的地址是否都為null進行判斷鸟整,如果都為空,則返回true朦蕴。
3篮条,上述依然不成立,則調(diào)用A的equals方法吩抓,執(zhí)行方法A.equals(B)涉茧。
- 注意String 類
1,String類對equals方法和==進行了override疹娶。
2伴栓,String類因為存在intern pool機制,詳情請見MSDN雨饺。因此兩個String比較的結(jié)果钳垮,可能與預期不符合。