C 比較物件的相等性 長文慎入

2021-10-06 08:04:49 字數 1974 閱讀 6135

system.object 定義了3個不同的方法來比較物件的相等性 : referenceequals() 和兩個版本的 equals(). 再加上比較運算子 == ,實際上有4種比較相等性的方法。 這些方法有一些細微的區別, 下面就介紹它們:

1. referenceequals() 方法

referenceequals() 是乙個靜態方法,其測試兩個引用是否指向類的同乙個例項, 特別是兩個引用是否包含記憶體中的相同位址。作為靜態方法,它不能重寫, 所以 system.object 的實現**保持不變。 如果提供的兩個引用指向同乙個例項, 則 referenceequals() 總是返回 true; 否則就返回 false。 但是它認為 null 等於 null 。 下面做個試驗:

public class testequals 

void main()

// 測試返回結果

false

true

true

2. equals() 虛方法

equals() 虛方法在自己的類中重寫它,從而按值來比較物件。 在重寫 equals()方法時要注意, 重寫的**不應丟擲異常。 同理,這是因為如果丟擲異常, 字典類就會出問題, 一些在內部呼叫這個方法的 .net 基類也可能出問題。

public class testequals

public testequals(string name)

// core

public override bool equals(object obj)

}void main()

// 輸出結果

false

true

3.靜態的equals()方法

靜態版本與虛版本的作用相同, 其區別是靜態版本帶有兩個引數,並對它們進行相等性比較。 這個方法可以處理兩個物件中有乙個是 null 的情況。 因此,如果乙個物件可能是 null ,這個方法就可以丟擲異常, 提供額外保護。靜態過載版本首先要檢查傳遞給它的引用是否為 null。 如果他們都是null 就返回 true(因為 null 與 null 相等)。 如果只有乙個引用是 null, 就返回false。 如果兩個引用實際上引用了某物件, 它就呼叫 equals 的虛例項版本。 這表示在重寫 equals的例項版本時, 其效果相當於也重寫了靜態版本。

void main()

// 輸出結果

false

true

4. 比較運算子 ==

最好將比較運算子看做嚴格的值比較和嚴格的引用比較。

void main()

// 輸出結果

false

true

比較值型別的相等性

在比較值型別的相等性時, 採用與引用型別相同的規則:referenceequals() 用於比較引用, equals() 用於比較值, == 可以看做是乙個中間項,既可以比較引用又可以比較值。 但最大的區別是值型別需要裝箱,才能把它們轉換為引用,進而才能對它們執行方法。 

這裡有乙個特別注意的地方就是 referenceequals() 在應用於值型別時總是返回 false,因為呼叫這個方法,值型別需要裝箱到物件中。造成引用不同,所以會總是返回false

bool b = referenceequals(v, v); // 這裡的兩個v會單獨進行裝箱操作,所以他們的引用會不同
出於上述原因, 呼叫referenceequals() 來比較值型別實際上沒有意義。

C 高階程式設計 比較物件的相等性

1.referenceequals 是乙個靜態方法,測試兩個引用是否引用類的同乙個例項,特別是兩個引用是否包含記憶體中的相同位址,它認為null等於null。2.虛擬的equals 該方法是虛擬的,所以可以在自己的類中重寫它,從而按值來比較物件。3.靜態的equals 與虛擬例項版本的作用相同,區別...

C 深入理解比較物件的相等性

引用型別都繼承自object型別,object型別有如下的用來比較物件相等性的方法 1 static bool referenceequals object obja,object objb 該方法是乙個靜態方法,比較的是兩個物件的引用,其中null等於null。2 virtual bool equ...

C 元組的相等性比較

元組作為輕量級的資料結構,在c 中具有廣泛的引用。但是元組的比較一直以來都是對於成員的依次比較。好在c 7.3開始,引入了元素的相等性比較,讓元組的易用性有了大幅提公升。微軟對此的介紹是 從 c 7.3 開始,元組型別支援 和 運算子。這些運算子按順序將左邊引數的每個成員與右邊引數的每個成員進行比較...