1. ReferenceEquals, == , Equals
Equals , == , ReferenceEquals都可以用于判斷兩個對象的個體是不是相等。
a) ReferenceEquals
ReferenceEquals是Object的靜态方法,用于比較兩個引用類型的對象是否是對于同一個對象的引用。對于值類型它總是傳回false。(因為Box以後的對象總是不同的,hehe)
b) ==是一個可以重載的二進制操作符,可以用于比較兩個對象是否相等。
對于内置值類型,==判斷的是兩個對象的代數值是否相等。它會根據需要自動進行必要的類型轉換,并根據兩個對象的值是否相等傳回true或者false。例如:
Int a = 100;
Double b =100;
If(a == b)
Console.WriteLine(“equal supports compare between different types!”);
上面這段程式将會輸出:
equal supports compare between different types!
而對于使用者定義的值類型,如果沒有重載==操作符,==将是不能夠使用的。例如:
Struct Userstruct1;
Userstruct1 a;
Userstruct1 b;
If(a == b)
Console.WriteLine(“can == reach this far?”)
上面的這段代碼是不能夠通過編譯的。可以通過重載使==作用于使用者定義的值類型。
對于引用類型,== 預設的行為與ReferenceEquals的行為相同,僅有兩個對象指向同一個Reference的時候才傳回true。但是.NET Framework中的類很多對==進行了重載,例如String類的==與Equals的行為相同,判斷兩個字元串的内容是否相等。是以在應用中,對于系統定義的引用類型建議不要使用==操作符,以免程式出現與預期不同的運作結果。
c) Equals 作為Object内置方法,Equals支援對于任意兩個CTS對象的比較。
Equals它有靜态方法和可重載的一個版本,下面的程式片斷解釋了這兩個方法的用法,
int a = 5;
int b = 5;
If(Object.Equals(a ,b))
// you can also use if(a.Equals(b))
{
Console.WriteLine(“a is equal to b”);
}
事實上,這兩個版本的結果完全相同,如果使用者重載了Equals,調用的都是使用者重載後的Equals。Equals的靜态方法的好處是可以不必考慮用于比較的對象是否為null。
Equals方法對于值類型和引用類型的定義不同,對于值類型,類型相同,并且數值相同(對于struct的每個成員都必須相同),則Equals傳回true,否則傳回false。而對于引用類型,預設的行為與ReferenceEquals的行為相同,僅有兩個對象指向同一個Reference的時候才傳回true。可以根據需要對Equals進行重載,例如String類的Equals用于判斷兩個字元串的内容是否相等。
StringBuilder a = new StringBuilder();
a.Append("the test a");
String s1 = a.ToString();
String s2 = "the test a";
if (s2 == s1)
Console.WriteLine("== returns true");
if (Object.Equals(s2, s1))
{
Console.WriteLine("equals returns true");
}
if (Object.ReferenceEquals(s2, s1))
{
Console.WriteLine("ReferenceEquals returns true");
}
這個執行個體将輸出:
== returns true
equals returns true
注:對于String類,直接聲明s1 = “the test a”的話,輸出結果将包含
"ReferenceEquals returns true",
因為預設的,String對于聲明的相同的字元串在堆上隻保留一個Copy,是以s1與s2将會指向相同的Reference,