[英]Difference between == operator and Equals() method in C#?
==
和Equals()
之間的區別是什么? 我知道==
用於比較運算符和Equals()
方法用於比較string的內容。所以我試過
// first example
string s1 = "a";
string s2 = "a";
Console.Write(a.Equals(s2)); // returns true, but if I assign "b" to s2,
// then result will be false
// second example
string s1 ="a";
string s2 ="a";
Console.Write(s1 == s2); // returns true
怎么會這樣? 兩者都是不同的對象引用。 假設我們認為這些是參考。 但我試着這樣使用
string s1 = new string("ab");
string s2 = new string("ab");
我得到編譯時錯誤,無法將字符串轉換為char
有幾件事正在發生。 首先,在這個例子中:
string s1 = "a";
string s2 = "a";
Console.WriteLine(s1 == s2);
你聲稱:
兩者都是不同的對象參考。
由於字符串實習,這不是真的。 s1
和s2
是對同一對象的引用。 C#規范保證 - 從C#4規范的2.4.4.5節:
當根據字符串相等運算符(第7.10.7節)等效的兩個或多個字符串文字出現在同一程序中時,這些字符串文字引用相同的字符串實例。
因此,在這種特殊情況下,即使您打印object.ReferenceEquals(s1, s2)
,或者如果您使用與==
的真實參考標識比較,您仍然會得到“true”:
object s1 = "a";
object s2 = "a";
Console.WriteLine(s1 == s2); // Still prints True due to string literal interning
但是,即使這些是對單獨對象的引用, ==
也會因string
而重載 。 重載是編譯時的決定 - 要使用的實現取決於操作數的編譯時類型。 例如:
string a = new string('x', 1);
string b = new string('x', 1);
Console.WriteLine(a == b); // Uses string's implementation, prints True
object c = a;
object d = b;
Console.WriteLine(c == d); // Reference identity comparison, prints False
將它與作為虛方法的object.Equals(object)
進行比較。 碰巧, String
也會重載此方法,但重要的是它會覆蓋它。 因此,如果我們將代碼更改為:
string a = new string('x', 1);
string b = new string('x', 1);
Console.WriteLine(a.Equals((object) b));
object c = a;
object d = b;
Console.WriteLine(c.Equals(d));
...然后編譯代碼中的兩個方法調用將只是object.Equals(object)
,但由於多態性,它們仍然都會打印True:將使用String
的實現。
以下是對重載方法的調用:
string a = new string('x', 1);
string b = new string('x', 1);
Console.WriteLine(a.Equals(b)); // Calls string.Equals(string)
引用Equals的文檔:
Equals的默認實現支持引用類型的引用相等,以及值類型的按位相等。 引用相等意味着被比較的對象引用引用相同的對象。 按位相等意味着被比較的對象具有相同的二進制表示。
和==運算符 :
對於預定義的值類型,如果操作數的值相等,則相等運算符(==)返回true,否則返回false。 對於除string之外的引用類型,如果其兩個操作數引用同一對象,則==返回true。 對於字符串類型,==比較字符串的值。
現在回到你的問題:為什么s1 == s2
返回true? 字符串是.NET中的特殊動物。 它們代表不可變的引用類型。 他們在.NET中實習。 這意味着如果您有2個具有相同值的字符串常量,它們將在運行時引用相同的對象實例。
從文檔中引用:
公共語言運行庫通過維護一個名為intern pool的表來保存字符串存儲,該表包含對在程序中以編程方式聲明或創建的每個唯一文字字符串的單個引用。 因此,具有特定值的文字字符串實例僅在系統中存在一次。
你的想法似乎是Java風格。 在java中, ==
運算符不能自定義,因此對於引用類型,它始終表示引用相等,而它表示基本類型的值相等。 另一方面, Equals
用於檢查引用類型中的值相等性。
不過,C#的情況有所不同。 Equals
和==
都可以有自定義實現。 區別在於Equals
是一個虛擬(實例)方法,而operator==
是一個靜態方法。 除此之外,他們可以以完全相同的方式行事。
默認情況下, Equals
和==
檢查引用類型的引用相等性,以及值類型的值相等性。 但是,對於string
,兩者都是自定義的以檢查值的相等性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.