【ASP.net】Equals 和 == 的區別
轉載:https://www.cnblogs.com/allenhua/p/5252473.html
在比較Equals 和 ==的區別前。我們先來了解下相關的知識
C#資料型別
1、值型別
值型別有:
值型別包括:簡單型別、結構型別、列舉型別;引用型別包括:Object 型別、類型別、介面、代表元、字串型別、陣列。
byte(1)、sbyte(1)、short(2)、ushort(2)、int(4)、uint(4)、long(8)、ulong(8)、float(4)、double(8)、decimal(8)、char、bool、列舉、結構。
上述中括號中的數字表示位元組數,byte、ushort、uint、ulong 為無符號型別(沒有負數),順便說一下 sbyte 是有符號的位元組。
2、引用型別
引用型別有:物件型別、類型別、介面、代表元、字串型別、陣列。
new 運算子
在 C# 中, new 關鍵字可用作運算子、修飾符或約束。
1、 new 運算子
用於建立物件和呼叫建構函式。
2、new 修飾符
用於向基類成員隱藏繼承成員。
3、new 約束
用於在泛型宣告中約束可能用作型別引數的引數的型別。
需注意一點:凡是用new運算子就會在堆記憶體中開闢空間存放引用(引用地址存放在棧上)物件的值
== 和 Equals 的區別
1. == 是一個運算子。
2.Equals則是string物件的方法,可以.(點)出來。
我們比較無非就是這兩種 1、基本資料型別比較 2、引用物件比較
1、基本資料型別比較
==和Equals都比較兩個值是否相等。相等為true 否則為false;
2、引用物件比較
==和Equals都是比較棧記憶體中的地址是否相等 。相等為true 否則為false;
需注意幾點:
1、string是一個特殊的引用型別。對於兩個字串的比較,不管是 == 和 Equals 這兩者比較的都是字串是否相同;
2、當你建立兩個string物件時,記憶體中的地址是不相同的,你可以賦相同的值。所以字串的內容相同。引用地址不一定相同,(相同內容的物件地址不一定相同),但反過來卻是肯定的;
3、基本資料型別比較(string 除外) == 和 Equals 兩者都是比較值;
接下來我們來挨個挨個看例項:
1、基本資料型別比較:== 和 Equals 都比較具體的值
int i1 = 8;
int i2 = 8;
bool bo1 = i1 == i2; //true
bool bo2 = (object)i1 == (object)i2; // 裝箱後變成引用型別,引用不同 故為false
bool bo3 = (i1).Equals(i2); //true 比較的是值 裝箱後 Equals比較的仍是值
2、來看一個地址不同,內容相同的比較。== 比較地址, Equals比較值
//使用了new運算子就會在記憶體中建立物件,地址是不相同的。字串內容相同
string str3 = new string(new char[] { 'a', 'b', 'c' });
string str4 = new string(new char[] { 'a', 'b', 'c' });
bool b3 = (object)str3 == (object)str4; //false 裝箱後 是比較地址,這裡記憶體中的地址是不相同的
bool b4 = ((object)str3).Equals((object)str4); //true 此時Equals依然是比較值
3、string字串比較:== 和 Equals 同樣也是比較具體的值
//string是特殊的引用型別。只要是字串比較,不管是"=="還是"Equals"都是比較字串的內容
string str1 = "abc";
string str2 = "abc";
bool b1 = str1 == str2; //true
bool b2 = str1.Equals(str2); //true
//使用了new運算子就會在記憶體中建立物件,地址是不相同的。字串內容相同
string str3 = new string(new char[] { 'a', 'b', 'c' });
string str4 = new string(new char[] { 'a', 'b', 'c' });
bool b3 = str3 == str4; //true 字串比較 是比較具體的值,這裡記憶體中的地址是不相同的
bool b4 = str3.Equals(str4); //true
bool b5 = str1 == str3; //true
bool b6 = (str1).Equals(str3); //true
object str5 = "abc"; //定義一個變數 str5並賦值為 abc
object str6 = "abc"; //定義一個變數 str6並指向字串abc
bool b7 = str5 == str6; //true
bool b8 = (object)str5 == (object)str6; //但這樣就是比較引用是否相同,因為str5 和 str6 引用同一個例項 即為 true
bool b9 = str5.Equals(str6); //true
在上個列子中b3和b4都是true,我們來看看str3和str4在記憶體中的地址是否相等?其實是不相等的。用new操作符建立的物件都會在記憶體中分配一個新的記憶體地址,同時也可以證明這裡比較的是值,而不是地址;更進一步證明相同內容的物件地址不一定相同。
如何調出記憶體視窗?如圖:(啟動除錯後,這裡可以調出多個記憶體視窗)用來比較地址
4、引用型別比較: ==和Equals都是比較棧記憶體中的地址是否相等
class MyClass
{
public string name;
public MyClass(string name)
{
this.name = name;
}
}
//------------------------測試-----------------------------
MyClass str7 = new MyClass("abc");
MyClass str8 = new MyClass("abc");
bool b10 = str7 == str8;
//這裡是引用型別比較(不是string字串比較)所有比較是不是對同一個物件的引用,這裡顯然是記憶體中兩個不同的引用物件。故為false
bool b11 = str7.Equals(str8); //同上
MyClass str9 = str7; //str7的地址賦值給str9。
bool bl2 = str7 == str9; //true 引用同一個物件
bool bl3 = str7.Equals(str9); //true
object str10 = new object();
object str11 = new object();
bool b12 = str10 == str11; //false
bool b13=str10.Equals(str11); //false
同樣我們開看看str7 str8 str9 分別在記憶體中的地址,紅框標記(str7,str9)可以看出地址是相等的
看到這裡也許你疑惑了,既然引用型別比較 == 和Equals都是比較地址,那就沒區別嗎?
Equals是string類下的一個方法,既然知道它的來路。我們就可以看看它內部原始碼的實現,開啟Reflector查詢string。找到Equals(Object obj) 和Equals(string value)
看到內部也是用==來實現的,並且看到Object的比較是轉換成string後比較。
好了,繼續來講,在引用型別比較中,== 和Equals都是比較地址外,Equals突出的地方。一個物件除了地址相同。還有其他獨有的特徵。比如我們要比較某人都來自中國(記憶體地址),並且都來自中國香港(記憶體地址獨有的特徵或性質),
當符合這兩個條件我們才說明這個物件是相等的。那麼此時 == 和Equals都無能為力。但Equals有它鶴立雞群的地方。
檢視Equals定義會發現,Equals是virtual方法: public virtual bool Equals(object obj); 既然是virtual我們就可以重寫Equals方法,來編寫自己的業務邏輯
嗯!來編寫一個測試類,並且override Equals方法
class MyClass
{
public string country; //國家
public string city; //城市
public MyClass(string country, string city)
{
this.country = country;
this.city = city;
}
public override bool Equals(object obj)
{
string ci = ((MyClass)obj).city;
string co = ((MyClass)obj).country;
if (ci == "香港" && co == "cn") return true;
return false;
}
}
測試:
MyClass str7 = new MyClass("cn","香港");
MyClass str8 = new MyClass("cn","香港");
MyClass str18 = new MyClass("cn", "臺灣");
bool na = str7.Equals(str8); //true
bool an = str7.Equals(str18); //false
最後談談這兩個有什麼區別:
string str1 = "abc";
string str3 = new string(new char[] { 'a', 'b', 'c' });
以上這兩句話大家應該都見得多,比如str3這句筆試題居多,大體都是建立了幾個string物件。回答理所當然是兩個。一個是存放在堆記憶體上資料"abc",一個是存在棧記憶體上對"abc"的引用,通俗一點就是棧上的引用地址指向堆中的值或內容。
來看看str1這句,這並沒有建立物件。即沒有在記憶體中分配空間。因為沒有使用new運算子,這裡僅僅是宣告瞭一個指向物件的引用變數str1,暫時指向"abc",所有這裡只建立了一個string物件,所有要區分new的方式
看看下面這個列子是建立了3個物件。因為字串是不可變的
string x = "ab";
string y = "a";
string x = x + y;
不知道C#中有沒有常量池這一概念。還有看到網上很多這樣的 string str = new string("abc") 可我真的沒找到stirng的這個過載函式
相關文章
- 【Java】equals 和 == 的區別Java
- ==和equals方法的區別
- java 中equals和==的區別Java
- equals()和hashCode()的區別
- Java中equals和==的區別Java
- equals和equalsIgnoreCase的區別
- Java中 equals() 方法和 == 的區別Java
- 深入理解equals和==的區別
- 在java中“equals”和“==”的區別Java
- "a".equals(b)和b.equals("a")有什麼區別
- 你真的知道 == 和 equals 的區別嗎?
- 你真的懂 == 和 equals 的區別嗎?
- Java基礎- ==和equals和hashCode的區別Java
- hashCode()和equals()的區別?(skycto JEEditor)
- 第四章 ==和equals()的區別
- Java經典面試題: == 和 equals( )的區別Java面試題
- javaSE中的==和equals的聯絡與區別Java
- C# 中的 == 和 equals()有什麼區別?C#
- Object類和String類equals方法的區別Object
- Java中(==)與equals的區別Java
- equals與==的區別(詳解)
- 深入探究Java中equals()和==的區別是什麼Java
- JAVA中字串比較equals()和equalsIgnoreCase()的區別Java字串
- Java面試題 equals()與"=="的區別?Java面試題
- Java常見知識點彙總(⑫)——==和equals的區別Java
- 程式設計師必須搞清的概念equals和=和hashcode的區別程式設計師
- Java基礎-- ==號與equals()方法的區別Java
- Java培訓教程:”==“和 equals 方法究竟有什麼區別?Java
- Java技術分享:”==“和 equals 方法究竟有什麼區別?Java
- java基本型別和包裝型別的“==”和equals()方法Java型別
- Java之String的equals與contentEquals區別Java
- Java中equals與==的本質區別是什麼?Java
- 還傻傻分不清楚equals和==的區別嗎?看完就明白了
- ASP.NET Core中GetService()和GetRequiredService()之間的區別ASP.NETUI
- java字串“==”與“equals”的差異及與c#的區別Java字串C#
- ASP.Net MVC與WebForm的區別ASP.NETMVCWebORM
- ../和./和/的區別
- java == 和equalsJava