== Equals ReferenceEquals 三個相等性測試,是.NET提供給程序員使用的三個方法,他們之間有什麼聯繫和區別,你真的仔細研究過?雖然以前也多多少少知道一點,可是有時候又不免混淆他們之間的概念和所適用的場合,決定作一個總結系統的描述這三個寶寶html
在編程中實際上咱們只須要這兩種比較,c#中類型也就這兩種程序員
(1)值類型的比較:通常咱們就是判斷兩個值類型實例的各自包含的值是否相等編程
(2)引用類型的比較:因爲引用類型在內存中的分佈有兩部分,一個是引用類型的引用(存在於線程棧中),一個是引用類型的值(存在於託管堆);因此咱們比較引用類型也就存在兩種比較c#
默認狀況下:值類型比較的是兩個值是否相等(不裝箱狀況下),引用類型比較的是兩個引用是否相等。安全
定義:靜態相等符號,對應存在的!=,這個符號是一個能夠重載的二元操做符,能夠用於比較兩個對象是否相等。使用==比較對象時,C#在編譯時就決定了所比較的類型,並且不會執行任何虛方法(Object.Equals)。這是你們所指望的相等行比較。ide
注意:可是某些內置的引用類型重載了==符號,例如string就重載==,使其比較的不是兩個字符串的引用,而是比較的兩個字符串字面量是否相等,以下圖,因此對於引用類型最好不要使用==符號進行相等性比較,避免混淆。【對於引用類型利用==除了string是比較其值外,其他都是比較其引用,由於string是常常須要操做,因此會直接比較其值,因此會對其特殊對待,因此若是碰見特殊的引用類型須要查看一下是否進行了==重載,默認狀況你們均可以把==在比較引用類型時當成比較引用!】測試
值類型的==比較:雖然i和j在棧上具備不一樣的內存空間,可是他們的代數值都爲5;m和n類型被自動轉換並比較代數值spa
int i = 5; int j = 5; Console.WriteLine(i == j);//值類型比較代數值 輸出True int m = 6; double n = 6.0; Console.WriteLine(m == n);//類型自動轉換並比較數值 輸出True
引用類型==比較:以下代碼,兩個object對象都在堆上申請了空間,在線程棧上存在兩個不一樣的引用,因此輸出結果爲False線程
object obj1 = new object(); object obj2 = new object(); Console.WriteLine(obj2==obj1);//引用類型比較引用 輸出False
3.2 Equals3d
定義:Equals屬於Object的實例方法,用於比較兩個對象的引用是否相等,注意:對於Object對象比較的是引用!
然而對於值類型,類型相同(不會進行類型自動轉換),而且數值相同(對於struct的每一個成員都必須相同),則Equals返回 true,不然返回false。這是爲何呢? 這是由於內置的值類型都重寫了Object.Equals方法,因此值類型的Equals方法與引用類型的Equals就產生了不一樣的效果。
Equals在程序運行時決定比較的類型--根據對象的實際類型進行比較,根據對象的類型調用他們各自的Equals虛方法。
int i = 5; int j = 5; Console.WriteLine(i.Equals(j));//值類型比較 輸出True int m = 6; double n = 6.0; Console.WriteLine(m.Equals(n));//類型不會自動轉換並比較數值 輸出False object obj1 = new object(); object obj2 = new object(); Console.WriteLine(obj2.Equals(obj1));//引用類型比較 輸出False Console.WriteLine(obj2.Equals(string.Empty));//輸出False,比較量對象的類型不一樣直接返回False
3.3 ReferenceEquals
定義:Object的靜態方法,比較兩對象的引用是否相等,值類型和引用類型都是同樣。
int i = 5; int j = 5; Console.WriteLine(object.ReferenceEquals(i, j));//輸出False int m = 6; double n = 6.0; Console.WriteLine(object.ReferenceEquals(m, n));//輸出False object obj1 = new object(); object obj2 = new object(); Console.WriteLine(object.ReferenceEquals(obj1, obj2));//輸出False
經過以上的探討咱們知道
ReferenceEquals比較對象的引用是否相同,並且是安全的比較
==和Equals異同
相同點: 對於值類型 都是比較代數值是否相等
不一樣點:(1)對於值類型比較,==會進行類型的自動轉換,而後比較代數值,Equals則不會進行轉換,先比較類型,再比較值,若是類型不一樣直接返回false
(2)==比較是安全的比較,也就是說兩對象爲任何值均可以進行比較,不會拋出異常;而Equals的比較則是不安全的,因爲在Equals在運行時纔會進行真正的比較,有可能調用Equals的調用者是NULL,編譯經過,可是運行時則會拋出異常
因此對於引用類型是要使用實例的Equals進行比較時,必定不要忘記檢查調用者對象是否爲空。而Object提供的靜態Equals方法也是安全的不須要檢查,下面的方法等效於Object提供的靜態Equals方法
public static bool AreEqual(object obj1, object obj2) { if (obj1 == null) return obj2 == null; return obj1.Equals(obj2); }
因爲本人才學識淺,描述不免紕漏,若有錯誤,歡迎指出。麼麼!
參考資料:
http://www.cnblogs.com/yang_sy/p/3582946.html
http://www.cnblogs.com/zagelover/articles/2741409.html