簡(jiǎn)單對(duì)比Equals、==和RefrenceEquals的區(qū)別
我們這里將簡(jiǎn)單對(duì)比Equals、==和RefrenceEquals的區(qū)別,我們將從引用類型的比較以及類型來進(jìn)行分析。
今天無意看到一篇有關(guān)Equals和==的區(qū)別的帖子,帖子中間簡(jiǎn)單的說成是比較引用和比較值,這樣的理解很有問題。
看了看MSDN,總結(jié)如下。
從兩個(gè)方面來說說這三者的區(qū)別。
先給出一個(gè)類和一個(gè)結(jié)構(gòu):
- public class RefrenceClass
- {
- public int X
- {get;set;}
- public string Y
- {get;set;}
- }
- public struct ValueStruct
- {
- public int x;
- public string y;
- }
1.引用類型的比較
看看以下這段代碼會(huì)輸出何種結(jié)果
- RefrenceClass c1 = new RefrenceClass();
- c1.X = 1;
- c1.Y = "OK";
- RefrenceClass c2 = new RefrenceClass();
- c2.X = 1;
- c2.Y = "OK";
- RefrenceClass c3 = new RefrenceClass();
- c3.X = 1;
- c3.Y = "OK!";
- RefrenceClass c4 = new RefrenceClass();
- c4.X = 2;
- c4.Y = "OK";
- RefrenceClass c5 = new RefrenceClass();
- c5=c1;
- c5.X = 2;
- RefrenceClass c6 = c1;
- Console.WriteLine(ReferenceEquals(c1,c2).ToString());
- Console.WriteLine(ReferenceEquals(c1,c3).ToString());
- Console.WriteLine(ReferenceEquals(c1,c4).ToString());
- Console.WriteLine(ReferenceEquals(c1,c5).ToString());
- Console.WriteLine(ReferenceEquals(c1,c6).ToString());
- Console.WriteLine();
- Console.WriteLine(Equals(c1,c2).ToString());
- Console.WriteLine(Equals(c1,c3).ToString());
- Console.WriteLine(Equals(c1,c4).ToString());
- Console.WriteLine(Equals(c1,c5).ToString());
- Console.WriteLine(Equals(c1,c6).ToString());
- Console.WriteLine();
- Console.WriteLine(c1.Equals(c2).ToString());
- Console.WriteLine(c1.Equals(c3).ToString());
- Console.WriteLine(c1.Equals(c4).ToString());
- Console.WriteLine(c1.Equals(c5).ToString());
- Console.WriteLine(c1.Equals(c6).ToString());
- Console.WriteLine();
- Console.WriteLine(c1==c2);
- Console.WriteLine(c1==c3);
- Console.WriteLine(c1==c4);
- Console.WriteLine(c1==c5);
- Console.WriteLine(c1==c6);
- Console.WriteLine();c1,c2,c3,c4為不同的實(shí)例,c1,c5,c6是同一個(gè)引用
返回的結(jié)果都是 前三個(gè)比較為false,后兩個(gè)為true
由結(jié)果看,靜態(tài)RefrenceEquals、靜態(tài)Equals、虛擬Equals和==比較的都是引用地址
而當(dāng)我們換成比較Struct的時(shí)候,靜態(tài)RefrenceEquals的結(jié)果均為false,靜態(tài)Equals、虛擬Equals的結(jié)果為true,false,false,false,true,==不可用在此處由這個(gè)結(jié)果看靜態(tài)Equals、虛擬Equals比較的是值
這就和我們上面得出的結(jié)果不一樣了,那到底比較的是什么呢?
我們按類型來分析:
1.靜態(tài)RefrenceEquals,從方法名也可以看出比較的是引用地址,在對(duì)值類型進(jìn)行此比較時(shí),始終為false,即使是RefrenceEauals(1,1),因?yàn)檫@里它把值首先裝箱再進(jìn)行比較,所以兩個(gè)的引用地址是不一樣的,但是RefrenceEquals(null,null)的值是true;
2.靜態(tài)Equals方法,這個(gè)方法其實(shí)最終是調(diào)用了虛擬Equals方法的不同重載
3.虛擬Equals方法,可在不同類中重載,這里我們就可以理解為什么上面的兩種不同類型變量的比較會(huì)有不同的結(jié)果了,比如String.Equals方法就是用于判斷兩個(gè)字符串的內(nèi)容是否相等
一般來說,對(duì)于值類型,類型相同,并且數(shù)值相同(對(duì)于struct的每個(gè)成員都必須相同),則Equals返回true,否則返回false。而對(duì)于引用類型,默認(rèn)的行為與ReferenceEquals的行為相同,僅有兩個(gè)對(duì)象指向同一個(gè)Reference的時(shí)候才返回true。靜態(tài)Equals相比虛擬Equals方法有一個(gè)優(yōu)點(diǎn),就在于它不用考慮比較的對(duì)象是否為null;
4.==運(yùn)算符,對(duì)于內(nèi)置的值類型,直接判斷兩個(gè)對(duì)象的值是否相等,并會(huì)根據(jù)需要對(duì)對(duì)象進(jìn)行類型轉(zhuǎn)換,對(duì)于用戶定義的值類型,比如struct,不可使用;杜宇引用類型,默認(rèn)的行為與ReferenceEquals的行為相同,但是很多類對(duì)==進(jìn)行了重載,比如String。
原文標(biāo)題:Equals、RefrenceEquals和==的區(qū)別
鏈接:http://www.cnblogs.com/solsolsol/archive/2009/09/17/1568421.html
【編輯推薦】