標籤:異常 man name imm 分享 seq height cts inter
聲明:本篇部落格翻譯自:https://www.codeproject.com/Articles/1111680/equalsequals-VS-Equals-in-Csharp
由於水平(技術水平+英語理解能力)有限/不足,肯定會有所疏漏/錯誤,請及時指正。
介紹:
在C#中,可以使用“==”和一個可重載的"Equals()"方法來對變數進行比較。但是很多開發人員並不知道兩者之間的區別。在這篇部落格中將討論兩者之間的區別和兩者的使用情境。"=="和"Equals()"比較沒有區別除了在做string的比較時。
比較規則:C#中的比較無非是對實值型別和參考型別進行比較。當對實值型別進行比較時,比較的是實值型別的“內容”;當對參考型別進行比較時,比較的是對象的引用是否相同(記憶體位址)而不是“內容”。上述規則對"=="和"Equals()"均適用。
情境一:實值型別比較
當對實值型別(int, double, byte etc)進行比較時, "=="和"Equals()"都是基於實值型別的內容比較。當實值型別的內容相同,則兩者相等。
Console.WriteLine("Value Type Compare...");int i = 10;int y = 10;Console.WriteLine(i == y); // trueConsole.WriteLine(i.Equals(y)); // true情境二:參考型別比較
當對參考型別(object, interface)進行比較時,比較的是引用(記憶體位址)是否相同,下面代碼中obj1和obj2使用"=="和“Equals”進行比較,結果為:false.儘管兩個對象的內容一樣的。但是內容地址不一樣。
class Customer{ public string Name { get; set; }}Customer obj1 = new Customer();obj1.Name = "Jimmy-Yang";Customer obj2 = new Customer();obj2.Name = "Jimmy-Yang";Console.WriteLine(obj1 == obj2); // falseConsole.WriteLine(obj1.Equals(obj2)); // false
如果obj1與obj2指向同一個引用(記憶體位址)。
Customer obj1 = new Customer();obj1.Name = "Jimmy-Yang";Customer obj2 = obj1;Console.WriteLine(obj1 == obj2); // trueConsole.WriteLine(obj1.Equals(obj2)); // true
情境三:string比較
string類型是參考型別,那麼下面代碼中"str"建立一個string對象,並且在堆記憶體塊上儲存"test"字元。當建立str1後,雖然儲存的內容一樣,但是應該儲存在不同的記憶體地區。
object str = "test";object str1 = "test";Console.WriteLine(str == str1); // trueConsole.WriteLine(str.Equals(str1)); // ture
執行結果發現str與str1是相等的。這是為什麼呢?
注意:C#的string類型遵循一條內部的規則。如果str與str1的內容相同,則兩者指向系統的的記憶體位址。因此“==”和"Equals"會返回true。
但是注意下面的代碼,我們建立了一個單獨對象,然後賦值給string類型。此時“==”比較將返回false,Equals()將返回true。這是兩者一個不同的地方。
object str = new string(new char[] { ‘t‘, ‘e‘, ‘s‘, ‘t‘ });object str1 = new string(new char[] { ‘t‘, ‘e‘, ‘s‘, ‘t‘ });Console.WriteLine(str == str1); // falseConsole.WriteLine(str.Equals(str1)); // true情境四:編譯時間VS運行時
兩者之間在做類型檢查時的區別。==在編譯時間做類型檢查;Equals()在運行時做類型檢查。請看下面的代碼,在“==”會有一個警告資訊。
情境五:NULL
當比較的對象為null時,“==”不會拋出異常,"Equals()"比較null對象時,會直接crash。
使用情境
"=="是C#提供的一個運算子,“Equals()”是基類提供的一個虛方法,可以在子類中繼承,並編寫自身比較邏輯。換句話說,“==”是一個C#的一個特性,而Equals是OOP的一個特性。兩者的區別一個基於單純的內容和引用(記憶體位址)比較。另一種是基於語義(Semantics, 此處我翻譯成語義,其實更確切的應該是對象之間的含義)上的比較。例如:1 <> 10 (從技術層面上講),但是現實生活中,1元=10角,此時1=10在含義上。
- 如果單純從技術層面上比較請使用“==”;
- 如果從語義上比較(例如:1元=10角),你需要使用Equals方法並提供合適的比較邏輯。
總結
請看下面的表格:
| |
== |
Equals |
| Usage |
Technical based |
Semantic based |
| Value types |
Content based Comparison |
Content based Comparison |
| Objects |
Reference based Comparison |
Reference based Comparison |
| String |
Content based Comparison |
Content based Comparison |
| String with no interning |
Reference based Comparison |
Content based Comparison |
| Type checking |
Compile time |
Run time |
| Nulls |
Works |
Can crash |
[C#] == VS Equals