在C#中比較兩個(gè)對(duì)象是否相等,通常有四種主要方式
1、ReferenceEquals(object o1, object o2):
靜態(tài)方法:比較兩個(gè)對(duì)象的引用,引用相同返回true,否則返回false,同為null是返回true;ReferenceEquals進(jìn)行值類型比較時(shí)總是返回false,因?yàn)閮蓚€(gè)值類型需要分別裝箱到對(duì)象中,是不同的引用?;
從名稱中便可知它用來(lái)比較兩者是否是相同的引用,我們也永遠(yuǎn)不應(yīng)該去重寫該方法。
Person zs = new Person("ZhangSan",28);
Person ls = new Person("LiSi",20);
Person zsCopy = zs;
//ReferenceEquals比較兩個(gè)對(duì)象的引用,同為null是返回true
Console.WriteLine("ReferenceEquals(zs, ls) : " + ReferenceEquals(zs, ls)); // False
Console.WriteLine("ReferenceEquals(zs, zsCopy) : " + ReferenceEquals(zs, zsCopy)); //True
Console.WriteLine("ReferenceEquals(ls, zsCopy) : " + ReferenceEquals(ls, zsCopy)); //Fasle
Console.WriteLine("ReferenceEquals(null, null) : " + ReferenceEquals(null, null)); //True
Console.WriteLine("ReferenceEquals(zs, null) : " + ReferenceEquals(zs, null)); //False
Console.WriteLine("ReferenceEquals(1, 1) : " + ReferenceEquals(1, 1)); //False
2、Equals(object o):
Person zs = new Person("ZhangSan",28);
Person ls = new Person("LiSi",20);
Person zsCopy = zs;
//虛擬Equals方法,比較引用,可以重寫比較值
Console.WriteLine("zs.Equals(ls) : " + zs.Equals(ls)); //Fasle
Console.WriteLine("zs.Equals(zsCopy) : " + zs.Equals(zsCopy)); //True
Console.WriteLine("ls.Equals(zsCopy) : " + ls.Equals(zsCopy)); //False
Console.WriteLine("zs.Equals(null) : " + zs.Equals(null)); //False
Console.WriteLine("1.Equals(1) : " + 1.Equals(1)); //True?
3、Equals(object o1, object o2)
Person zs = new Person("ZhangSan",28);
Person ls = new Person("LiSi",20);
Person zsCopy = zs;
//靜態(tài)Equals方法先比較兩個(gè)對(duì)象是否為空,如果都不為空,則調(diào)用虛擬Equals方法
Console.WriteLine("Person.Equals(zs, ls) : " + Person.Equals(zs, ls)); //False
Console.WriteLine("Person.Equals(zs, zsCopy) : " + Person.Equals(zs, zsCopy)); //True
Console.WriteLine("Person.Equals(ls, zsCopy) : " + Person.Equals(ls, zsCopy)); //False
Console.WriteLine("Person.Equals(null, null) : " + Person.Equals(null, null)); //True
Console.WriteLine("Person.Equals(zs, null) : " + Person.Equals(zs, null)); //Fasle
Console.WriteLine("Person.Equals(1, 1) : " + Person.Equals(1, 1)); //True
4、object1 == object2:
比較運(yùn)算符:可以重寫;對(duì)于引用類型,默認(rèn)是比較引用的(System.String除外)來(lái)源,對(duì)于值類型默認(rèn)比較值;
對(duì)于自定義的結(jié)構(gòu),如果不顯示重載operator方法,則無(wú)法使用。
由于在C#中要求比較運(yùn)算符必須成對(duì)重載,重載==運(yùn)算符的同時(shí)也必須重載!=運(yùn)算符,否則也會(huì)產(chǎn)生編譯錯(cuò)誤。
如果要重載的話,運(yùn)算符"=="、"!="?與?Equals方法、GetHashCode方法應(yīng)該同時(shí)被重載,因?yàn)樗麄儜?yīng)該保持同樣的相等邏輯。但不要再==中調(diào)用Equals,最好是在Equals中調(diào)用==。
Person zs = new Person("ZhangSan",28);
Person ls = new Person("LiSi",20);
Person zsCopy = zs;
String str1 = "Hello";
String str2 = "Hello";
String str3 = str1;
//比較運(yùn)算符比較引用,可以重寫
Console.WriteLine("zs == ls : " + (zs == ls)); //False
Console.WriteLine("zs == zsCopy : " + (zs == zsCopy)); //True
Console.WriteLine("ls == zsCopy : " + (ls == zsCopy)); //False
Console.WriteLine("zs == null : " + (zs == null)); //False
Console.WriteLine("1 == 1 : " + (1 == 1)); //True
Console.WriteLine("str1 == str2 :" + (str1 == str2));//True
Console.WriteLine("str1 == str3 :" + (str1 == str3));//True
Console.WriteLine("str2?==?str3?:"?+?(str2?==?str3));//True
Equals(object?o)與==的區(qū)別
1) ==操作符判斷的是堆棧中的值,Equlas判斷的是堆中的值。
2) C#提供值類型和引用類型:
值類型存儲(chǔ)在棧上,故用==判斷是直接判斷其值是否相等,因?yàn)橹殿愋筒淮嬖诙阎械臄?shù)據(jù),因此值類型的Equals也是判斷數(shù)據(jù)。即,對(duì)于值類型而言,==與Equals相同,均是判斷其值是否相等。
對(duì)于引用類型而言,其棧中存儲(chǔ)的是對(duì)象的地址,那么==就是比較兩個(gè)地址是否相等,即是否指向同一個(gè)對(duì)象;Equals則是比較兩個(gè)對(duì)象在堆中的數(shù)據(jù)是否一樣,即兩個(gè)引用類型是否是對(duì)同一個(gè)對(duì)象的引用。
?3) String類型特殊:
4) 與GetHashCode()的關(guān)系
出處:cnblogs.com/LXLR/archive/2023/07/16/17558349.html?
作者:LXLR
該文章在 2025/4/28 13:07:45 編輯過