c#中Equals()與==的比較
阿新 • • 發佈:2020-12-24
背景
平常寫程式碼時,遇到兩個String型別比較,在c#中直接使用==
,但是回頭想一想同樣是面向物件的Java中==
比較是物件在記憶體中的首地址,沒理由c#會如此獨特,為了瞭解c#的Equals()
與==
,寫下這份筆記以提醒自己。
1.Equals()與==的相同之處
首先這裡比較兩個字串,看看他們的結果是什麼
string s1 = "Hello";
string s2 = "Hello";
string s3 = "hello";
s1.Equals(s2)// 結果為:true
s1.Equals(s3) //結果為:false
s1 == s2//結果為:true
s1 == s3//結果為:false
從執行的結果可以看到在這裡兩者的效果是相同的。因此總會有這麼一句總結:對於值型別,==和Equals()等價,都是比較儲存資訊的內容(即比較兩個物件的值是否相同)
如果這時我們就說兩者是等價的未免也太心急了一點,我們翻開某某資料的時候查閱==和Equals()時會有:==號是比較兩個引用型別的變數的引用是否一致。現在先說為什麼我們使用的時候沒有感覺到其中的區別,原因在於微軟大牛們對==
這個方法進行了重寫。這裡貼張網上的圖:
2.Equals()與==的不同
上面提到==是比較兩個引用型別的變數的引用是否一致,從兩個字串的比較中我們沒有看出來,那麼現在我們比較兩個物件,這樣就可以展示他們之間的不同,以及==
string s1 = new string(new char[] { 'a', 'b' });
string s2 = new string(new char[] {'a', 'b' });
object objs1 = (object)s1;
object objs2 = (object)s2;
Console.WriteLine(objs1 == objs2);//False
Console.WriteLine(objs1.Equals(objs2));//True
從執行的結果上可以看出於:除string之外的引用型別,==比較的是是否指向同一個堆中地址,Equals()判斷內容是否相同。而Equals有這樣的效果是因為在C#語言中,過載了Object物件的很多方法(包括equals()方法),使string物件用起來就像是值型別一樣
在測試的時候我寫了如下的程式碼,思路和上面一樣,但是結果卻是不一樣的。
string s1 = "ab";
string s2 = "ab";
object objs1 = (object)s1;
object objs2 = (object)s2;
Console.WriteLine(objs1 == objs2);//True
Console.WriteLine(objs1.Equals(objs2));//True
怎麼?難道是我vs出錯了,經過檢查發現系統並沒有給字串s2分配記憶體,只是將"ab"指向了s2。所以s1和s2指向的是同一個字串(字串在這種賦值的情況下做了記憶體的優化)
當然,如果我們比較的是自定義的其他引用型別,那麼兩者都是比較的引用的地址,而非內容。例如:
Boss boss1 = new Boss("經理");
Boss boss2 = new Boss("經理");
// 兩個都是領導,不需要和我這個職工比較
Console.WriteLine(boss1 == boss);//False
Console.WriteLine(boss1.Equals(boss2));//False
看來就==和Equals就有這麼多可以學到的東西,自己還是勉勵加油呀!