2017-08-29 102 views
5

我混亂有關(C#) 使用==當我用文字串像這裏使用==操作符:混亂在C#

object a="hello"; 
object b="hello"; 

比較a==b將是真實的。

但是當我使用對象喜歡這裏:

object c=new StringBuilder("hello").ToString(); 
object d=new StringBuilder("hello").ToString(); 

比較a==b將是錯誤的。

即使a,b,c,d編譯時的所有類型System.Object和 ==運算符比較值取決於它們在編譯時的值。

我使用擴展方法在編譯時得到varabiles類型:

public static class MiscExtensions 
{ 
    public static Type GetCompileTimeType<T>(this T dummy) 
    { return typeof(T); } 
} 
+3

與'=='相比,Interned字符串對象作爲引用相等將返回false(請參閱https://stackoverflow.com/questions/1766492/overloading-operator-versus-equals)。 –

+0

我認爲你對C#中的不同類型更加困惑。 「Object」,「string」和「StringBuilder」是不一樣的,這就是爲什麼它們有不同的名字。 ;) – waka

+0

類似的問題在這裏:https://stackoverflow.com/questions/27710665/comparing-values-using-operator – Winnie

回答

17
object a="hello"; 
object b="hello"; 

這裏編譯器創建的文字"hello"一個string實例。所以ab指向相同的實例。

在你的第二個片段cd不同string實例。然而

重要的一點是,a == bc == d不叫==運營商string類的,但object。所以一個簡單的參考比較被執行,而不是string比較。

+0

@mark看看官方文檔。他們說平等是通過引用來完成的,而不是字符串。 RenéVogt對這個答案是正確的 – OrcusZ

1

當您使用常量字符串「hello」,編譯器會產生這個字符串的實習版本,並使用該值既是和b。

當您使用StringBuilder和ToString時,會比較包含「hello」的兩個單獨的字符串實例。

如果您想查詢字符串是否相等,你應該使用equals()方法

7

注意這裏,你是比較object,而不是string

這將給予真:

string c = new StringBuilder("hello").ToString(); 
string d = new StringBuilder("hello").ToString(); 

c == d; // true 

或該:

var c = new StringBuilder("hello").ToString(); 
var d = new StringBuilder("hello").ToString(); 

c == d; // true 

(因爲在這種情況下,var將隱式輸入變量作爲表達式,StringBuilder.ToString(),結果其是string),參見here以獲得更多信息


不要混合object比較和string比較。

在你的基本案例中,比較導致了真實,因爲它實際上是同一個對象!

在第二種情況下,您有兩個「新」語句,因此兩個不同的字符串生成器會生成兩個新的字符串對象。不一樣的常量字符串對象。

使用的比較取決於您的變量類型。

+1

添加到此答案中,這是一個鏈接[更詳細地解釋var-keyword](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/var) – waka

+0

yes,我會在我的回答中加上一句話,謝謝 – Pac0

2

對於字符串以外的引用類型,如果其兩個 操作數引用同一對象,則==會返回true。

在第一個例子:

object a="hello"; 
object b="hello"; 

一個b指向同一個對象,所以它們是相等的,但在第二:

object c=new StringBuilder("hello").ToString(); 
object d=new StringBuilder("hello").ToString(); 

創建兩個不同的StringBuilder的實例:cd,使它們指向不同的對象,並不等於

更多細節,你可以找到Microsoft Docs

2

msdn page

對於預定義的值的類型,如果 的操作數的值相等,否則爲假相等運算符(==)返回true。對於參考 字符串以外的其他類型,如果其兩個操作數引用 相同的對象,則==返回true。對於字符串類型,==會比較 字符串的值。

所以這兩個比較不應該是平等的,因爲你是專門鑄造對象而不是字符串。

但是,c#編譯器已經過優化,並且認識到您正在使用兩個相同的字符串文字,因此編譯器會將兩個字符串合併爲一個對象,因此對象比較爲真。但編譯器無法合併StringBuilder實例,因爲您正在使用new關鍵字構造新對象。

1
object a="hello"; 
object b="hello"; 

這裏a和b都指向相同的對象。具體來說,它們指向相同的內存。而在第二個例子中

object c=new StringBuilder("hello").ToString(); 
object d=new StringBuilder("hello").ToString(); 

在這裏,您正在創建一個新實例,具體而言,內存位置因c和d而異。 所以這就是a == b和c!= d的原因。