日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

区别和认识四个判等函数

發(fā)布時間:2025/5/22 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 区别和认识四个判等函数 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Net有四個判等函數(shù)?不少人看到這個標(biāo)題,會對此感到懷疑。事實上確是如此,.Net提供了ReferenceEquals、靜態(tài)Equals,具體類型的Equals以及==操作符這四個判等函數(shù)。但是這四個函數(shù)之間有細(xì)微的關(guān)系,改變其中一個函數(shù)的實現(xiàn)會影響到其他函數(shù)的操作結(jié)果。

?

首先要說的是Object.ReferenceEquals和Object.Equals這兩個靜態(tài)函數(shù),對于它們倆來說,是不需要進(jìn)行重寫的,因為它們已經(jīng)完成它們所要得做的操作。

?

對于Object.ReferenceEquals這個靜態(tài)函數(shù),函數(shù)形勢如下:

public static bool ReferenceEquals( object left, object right );

?

這個函數(shù)就是判斷兩個引用類型對象是否指向同一個地址。有此說明后,就確定了它的使用范圍,即只能對于引用類型操作。那么對于任何值類型數(shù)據(jù)操作,即使是與自身的判別,都會返回false。這主要因為在調(diào)用此函數(shù)的時候,值類型數(shù)據(jù)要進(jìn)行裝箱操作,也就是對于如下的形式來說。

??? int n = 10;

??? Object.ReferenceEquals( n, n );

?

這是因為對于n這個數(shù)據(jù)裝箱兩次,而每次裝箱后的地址有不同,而造成Object.ReferenceEquals( n, n )的結(jié)果永遠(yuǎn)為false。

?

對于第一個判等函數(shù)來說,沒有什么好擴(kuò)展的,因為本身已經(jīng)很好地完成了它所要做的。

?

對于第二個Object.Equals這個靜態(tài)函數(shù),其形式如下:

public static bool Equals( object left, object right );

?

按照書中對它的分析,其大致函數(shù)代碼如下:

??? public static void Equals( object left, object right )

??? {

??????? // Check object identity

??????? if( left == right )

??????????? return true;

?

??????? // both null references handled above

??????? if( ( left == null ) || ( right == null ) )

??????????? return false;

?

??????? return left.Equals( right );

??? }

?

可以說,Object.Equals這個函數(shù)完成判等操作,需要經(jīng)過三個步驟,第一步是需要根據(jù)對象所屬類型的==操作符的執(zhí)行結(jié)果;第二步是判別是否為null,也是和第一步一樣,需要根據(jù)類型的==操作符的執(zhí)行結(jié)果;最后一步要使用到類型的Equals函數(shù)的執(zhí)行結(jié)果。也就是說這個靜態(tài)函數(shù)的返回結(jié)果,要取決于后面要提到的兩個判等函數(shù)。類型是否提供相應(yīng)的判等函數(shù),成為這個函數(shù)返回結(jié)果的重要因素。

?

那么對于Object.Equals這個靜態(tài)方法來說,雖說接受參數(shù)的類型也屬于引用類型,但是不同于Object.ReferenceEquals函數(shù),對于如下的代碼,能得出正確的結(jié)果。

??? int n = 10;

??? Debug.WriteLine( string.Format( "{0}", Object.Equals( n, n ) ) );

??? Debug.WriteLine( string.Format( "{0}", Object.Equals( n, 10 ) ) );

?

這是因為在此函數(shù)中要用到具體類型的兩個判等函數(shù),不過就函數(shù)本身而言,該做的判斷都做了,因此不需要去重載添加復(fù)雜的操作。

?

為了更好的述說剩下兩個函數(shù),先解釋一下等價的意義。對于等價的意義,就是自反、對稱以及傳遞。

所謂自反,即a == a;

而對稱,是a == b,則b == a;

傳遞是 a == b,b == c,則 a == c;

理解等價的意義后,那么在實現(xiàn)類型的判等函數(shù)也要滿足這個等價規(guī)則。

?

對于可以重載的兩個判等函數(shù),首先來介紹的是類型的Equals函數(shù),其大致形式如下:

public override bool Equals( object right );

?

那么對于一個類型的Equals要做些什么操作呢,一般來說大致如下:

??? public class KeyData

??? {

??????? private int nData;

??????? public int Data

??????? {

??????????? get{ return nData;}

??????????? set{ nData = value; }

??????? }

?

??????? public override bool Equals( object right )

??????? {

??????????? //Check null

??????????? if( right == null )

??????????????? return false;

?

??????????? //check reference equality

??????????? if( object.ReferenceEquals( this, right ) )

??????????????? return true;

?

??????????? //check type

??????????? if( this.GetType() != right.GetType() )

??????????????? return false;

?

??????????? //convert to current type

??????????? KeyData rightASKeyData = right as KeyData;

?

??????????? //check members value

??????????? return this.Data == rightASKeyData.Data;

??????? }

??? }

?

如上增加了一個類型檢查,即

if( this.GetType() != right.GetType() )

這部分,這是由于子類對象可以通過as轉(zhuǎn)化成基類對象,從而造成不同類型對象可以進(jìn)行判等操作,違反了等價關(guān)系。

?

除此外對于類型的Equals函數(shù)來,其實并沒有限制類型非要屬于引用類型,對于值類型也是可以重載此函數(shù),但是我并不推薦,主要是Equals函數(shù)的參數(shù)類型是不可變的,也就是說通過此方法,值類型要經(jīng)過裝箱操作,而這是比較影響效率的。

?

而對于值類型來說,我推薦使用最后一種判等函數(shù),即重載運(yùn)算符==函數(shù),其大致形式如下:

public static bool operator == ( KeyData left,? KeyData right );

?

對于一個值類型而言,其的大致形式應(yīng)該如下:

??? public struct KeyData

??? {

??????? private int nData;

??????? public int Data

??????? {

??????????? get{ return nData;}

??????????? set{ nData = value; }

??????? }

?

??????? public static bool operator == ( KeyData left,? KeyData right )

??????? {

??????????? return left.Data == right.Data;

??????? }

?

??????? public static bool operator != ( KeyData left, KeyData right )

??????? {

??????????? return left.Data != right.Data;

??????? }

??? }

?

由于==操作與!=操作要同步定義,所以在定義==重載函數(shù)的時候,也要定義!=重載函數(shù)。這也是.Net在判等操作保持一致性。那么對于最后一個判等函數(shù),這種重載運(yùn)算符的方法并不適合引用類型。這就是.Net經(jīng)常現(xiàn)象,去判斷兩個引用類型,不要用==,而要用某個對象的Equals函數(shù)。所以在編寫自己類型的時候,要保留這種風(fēng)格。

?

那么對于以上介紹的四種判等函數(shù),會產(chǎn)生如下類似的對比表格。

?
?操作結(jié)果取決于
?適用范圍
?建議
?
Object.ReferenceEquals
?兩個參數(shù)對象是否屬于同一個引用
?引用類型
?不要用它來判斷值類型數(shù)據(jù)
?
Object.Equals
?參數(shù)類型自身的判等函數(shù)
?無限制
?考慮裝箱操作對值類型數(shù)據(jù)產(chǎn)生的影響
?
類型的Equals
?類型重載函數(shù)
?無限制
?考慮裝箱操作對值類型數(shù)據(jù)產(chǎn)生的影響
?
類型的==重載
?類型重載函數(shù)
?無限制
?不要在引用類型中重載此運(yùn)算符
?

?

那么在編寫類型判等函數(shù)的時候,要注意些什么呢,給出如下幾點(diǎn)建議。

首先,要判斷當(dāng)前定義的類型是否具有判等的意義;

其次,定義類型的判等函數(shù)要滿足等價規(guī)則;

最后一點(diǎn),值類型最好不要重載定義Equals函數(shù),而引用類型最好不要重載定義==操作符。

?

本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/Knight94/archive/2006/08/11/1050901.aspx

總結(jié)

以上是生活随笔為你收集整理的区别和认识四个判等函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。