c#有四種判斷相等的方法?不少人看到這個標題,會對此感到懷疑。事實上確是如此,。net提供了referenceequals、靜態equals,具體型別的equals以及==操作符這四個判等函式。但是這四個函式之間有細微的關係,改變其中乙個函式的實現會影響到其他函式的操作結果。
首先要說的是object.referenceequals和object.equals這兩個靜態函式,對於它們倆來說,是不需要進行重寫的,因為它們已經完成它們所要得做的操作。對於object.referenceequals這個靜態函式,函式形勢如下:
public static bool referenceequals( object left, object right );
這個函式就是判斷兩個引用型別物件是否指向同乙個位址。有此說明後,就確定了它的使用範圍,即只能對於引用型別操作。那麼對於任何值型別資料操作,即使是與自身的判別,都會返回false.這主要因為在呼叫此函式的時候,值型別資料要進行裝箱操作,也就是對於如下的形式來說。
int n = 10;
object.referenceequals( n, n );
這是因為對於n這個資料裝箱兩次,而每次裝箱後的位址有不同,而造成object.referenceequals( n, n )的結果永遠為false.
對於第乙個判等函式來說,沒有什麼好擴充套件的,因為本身已經很好地完成了它所要做的。
對於第二個object.equals這個靜態函式,其形式如下:
public static bool equals( object left, object right );
按照書中對它的分析,其大致函式**如下:
public static void equals( object left, object right )
可以說,object.equals這個函式完成判等操作,需要經過三個步驟,第一步是需要根據物件所屬型別的==操作符的執行結果;第二步是判別是否為null,也是和第一步一樣,需要根據型別的==操作符的執行結果;最後一步要使用到型別的equals函式的執行結果。也就是說這個靜態函式的返回結果,要取決於後面要提到的兩個判等函式。型別是否提供相應的判等函式,成為這個函式返回結果的重要因素。
那麼對於object.equals這個靜態方法來說,雖說接受引數的型別也屬於引用型別,但是不同於object.referenceequals函式,對於如下的**,能得出正確的結果。
int n = 10;
debug.writeline( string.format( "", object.equals( n, n ) ) );
debug.writeline( string.format( "", object.equals( n, 10 ) ) );
這是因為在此函式中要用到具體型別的兩個判等函式,不過就函式本身而言,該做的判斷都做了,因此不需要去過載新增複雜的操作。
為了更好的述說剩下兩個函式,先解釋一下等價的意義。對於等價的意義,就是自反、對稱以及傳遞。
所謂自反,即a == a;
而對稱,是a == b,則b == a;
傳遞是 a == b,b == c,則 a == c;
理解等價的意義後,那麼在實現型別的判等函式也要滿足這個等價規則。
對於可以過載的兩個判等函式,首先來介紹的是型別的equals函式,其大致形式如下:public override bool equals( object right );
那麼對於乙個型別的equals要做些什麼操作呢,一般來說大致如下:
public class keydata
set} public override bool equals( object right )
}
如上增加了乙個型別檢查,即
if( this.gettype() != right.gettype() )這部分,這是由於子類物件可以通過as轉化成基類物件,從而造成不同型別物件可以進行判等操作,違反了等價關係。
除此外對於型別的equals函式來,其實並沒有限制型別非要屬於引用型別,對於值型別也是可以過載此函式,但是我並不推薦,主要是equals函式的引數型別是不可變的,也就是說通過此方法,值型別要經過裝箱操作,而這是比較影響效率的。
public static bool operator == ( keydata left, keydata right );
對於乙個值型別而言,其的大致形式應該如下:
public struct keydata
set} public static bool operator == ( keydata left, keydata right )
public static bool operator != ( keydata left, keydata right )
}
由於==操作與!=操作要同步定義,所以在定義==過載函式的時候,也要定義!=過載函式。這也是。net在判等操作保持一致性。那麼對於最後乙個判等函式,這種過載運算子的方法並不適合引用型別。這就是。net經常現象,去判斷兩個引用型別,不要用==,而要用某個物件的equals函式。所以在編寫自己型別的時候,要保留這種風格。
那麼對於以上介紹的四種判等函式,會產生如下類似的對比**。操作結果取決於 適用範圍 建議object.referenceequals 兩個引數物件是否屬於同乙個引用 引用型別 不要用它來判斷值型別資料object.equals 引數型別自身的判等函式 無限制 考慮裝箱操作對值型別資料產生的影響型別的equals 型別過載函式 無限制 考慮裝箱操作對值型別資料產生的影響型別的==過載 型別過載函式 無限制 不要在引用型別中過載此運算子;那麼在編寫型別判等函式的時候,要注意些什麼呢,給出如下幾點建議。
首先,要判斷當前定義的型別是否具有判等的意義;
其次,定義型別的判等函式要滿足等價規則;
最後一點,值型別最好不要過載定義equals函式,而引用型別最好不要過載定義==操作符
JS型別判斷的四種方法
1.typeof typeof是乙個操作符,其右側跟乙個一元表示式,並返回這個表示式的資料型別。返回的結果用該型別的字串 全小寫字母 形式表示,包括number,string,boolean,undefined,object,function,symbol等。複製 typeof string typ...
C 中物件的四種相等比較方式
c 中物件的四種相等比較方式如下 1.referenceequals object o1,object o2 比較兩個物件的引用,引用相同返回true,否則返回false,同為null是返回true 2.equals object o 虛擬equals方法,比較引用,可以重寫比較值 3.equals...
判斷資料型別的四種方法
typeof typeof 一般用於判斷基本型別null除外,typeof也可以判斷function 但判斷array,error,null 這幾個引用型別時對會被typeof判斷為object,所以如果想判斷這幾種資料型別,就不能使用 typeof 了,比較有侷限性 instanceof inst...