程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Equals、RefrenceEquals和==的區別

Equals、RefrenceEquals和==的區別

編輯:關於.NET

今天無意看到一篇有關Equals和==的區別的帖子,帖子中間簡單的說成是比較引用和比較值,這樣的理解很有問題。

看了看MSDN,總結如下。

從兩個方面來說說這三者的區別。

先給出一個類和一個結構:

public class RefrenceClass
{
public int X
{get;set;}

public string Y
{get;set;}
}

public struct ValueStruct
{
public int x;
public string y;
}

1.引用類型的比較

看看以下這段代碼會輸出何種結果

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為不同的實例,c1,c5,c6是同一個引用

返回的結果都是 前三個比較為false,後兩個為true

由結果看,靜態RefrenceEquals、靜態Equals、虛擬Equals和==比較的都是引用地址

而當我們換成比較Struct的時候,

靜態RefrenceEquals的結果均為false,靜態Equals、虛擬Equals的結果為true,false,false,false,true,==不可用在此處

由這個結果看靜態Equals、虛擬Equals比較的是值

這就和我們上面得出的結果不一樣了,那到底比較的是什麼呢?

我們按類型來分析:

1. 靜態RefrenceEquals,從方法名也可以看出比較的是引用地址,在對值類型進行此比較時,始終為false,即使是 RefrenceEauals(1,1),因為這裡它把值首先裝箱再進行比較,所以兩個的引用地址是不一樣的,但是 RefrenceEquals(null,null)的值是true;

2.靜態Equals方法,這個方法其實最終是調用了虛擬Equals方法的不同重載

3.虛擬Equals方法,可在不同類中重載,這裡我們就可以理解為什麼上面的兩種不同類型變量的比較會有不同的結果了,比如String.Equals方法就是用於判斷兩個字符串的內容是否相等

一般來說,對於值類型,類型相同,並且數值相同(對於struct的每個成員都必須相同),則Equals返回true,否則返回false。而對於引用類型,默認的行為與ReferenceEquals的行為相同,僅有兩個對象指向同一個Reference的時候才返回true。

靜態Equals相比虛擬Equals方法有一個優點,就在於它不用考慮比較的對象是否為null;

4.== 運算符,對於內置的值類型,直接判斷兩個對象的值是否相等,並會根據需要對對象進行類型轉換,對於用戶定義的值類型,比如struct,不可使用;杜宇引用類型,默認的行為與ReferenceEquals的行為相同,但是很多類對==進行了重載,比如String。

一些總結,不當之處,請指出。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved