2010-08-03 70 views
42

在C#中,你可以隱式將字符串和我們說,一個整數:string = string + int:背後是什麼?

string sth = "something" + 0; 

我的問題是:

  1. 爲什麼,通過假定的事實,你可以隱式將字符串和一INT,C#不允許初始化字符串是這樣的:

    string sth = 0; // Error: Cannot convert source type 'int' to target type 'string' 
    
  2. 如何C#蒙上0作爲字符串。它是0.ToString()還是(string)0還是別的?

  3. 如何找到前面問題的回答?
+15

我特別喜歡你如何問「如何找到前一個問題的答案?」 – 2010-08-03 17:48:09

回答

44

它編譯到呼叫到String.Concat(object, object),像這樣:

string sth = String.Concat("something", 0); 

(請注意,該特定線將實際被編譯器優化掉)

該方法被定義如下: (從.NET參考源獲取)

public static String Concat(Object arg0, Object arg1) { 
     if (arg0==null) { 
      arg0 = String.Empty; 
     } 

     if (arg1==null) { 
      arg1 = String.Empty; 
     } 
     return Concat(arg0.ToString(), arg1.ToString()); 
    } 

(這需要String.Concat(string, string)


要發現這一點,你可以用ildasm,或反思(IL或C#中,沒有優化),看看有什麼+行編譯成。

+6

SLaks是正確的,但要解釋OP的問題: 1)「+」是字符串和對象之間的重載操作符 2)是,.ToString()最終被調用爲 3)反射器 – 2010-08-03 16:36:15

+0

然後調用'ToString'在這兩個對象... – 2010-08-03 16:36:29

+0

另請參見[這個答案](http://stackoverflow.com/questions/3312504/why-is-there-no-exception-when-adding-null-to-a-string/3312509# 3312509)。 – SLaks 2010-08-03 16:40:13

20

這在C#4規範的7.8.4節中指定:

對於形x + y, 二元運算符重載解析的操作 (§7.3.4)被施加到選擇 特定的運營商實施的操作數 被轉換爲 參數類型所選擇的操作者 的,結果 的類型是運營商的返回類型。

的預定義的加法運算符 如下所列。對於數字和 枚舉類型,預定義 加法運算符計算的 兩個操作數的總和。當一個或兩個 操作數是字符串類型,所述預定義的 加法運算 串聯操作數的字符串表示 。

的最後一句話是最相關的一個這種情況。

再後來:

字符串連接

string operator +(string x, string y); 

string operator +(string x, object y); 

string operator +(object x, string y); 

二進制+ 操作者的這些重載執行字符串連接。 如果字符串連接的操作數 爲空,則替換爲空字符串 。否則,通過調用從類型 對象繼承的虛擬 ToString方法,將任何非字符串 參數轉換爲其字符串 。如果ToString返回null,則替換空字符串 。

指定如何將整數轉換爲字符串。

而結果:

字符串連接的結果 操作是由左操作 其次 右操作數的字符 中字符的字符串。字符串 並置運算符永遠不會返回空值 。

執行級聯的實際方法是實現特定的,但正如在其他答案中指出的,MS實現使用string.Concat

+0

''abc「+ 123'是否會導致123被裝箱?會''abc「+ 123.ToString()'是最低效率更高? – andleer 2015-04-23 20:22:14

+2

@andleer:它是特定於實現的,但是,它的確如此......理論上講,'123.ToString()'會更高效,但JIT有可能知道這種模式。 – 2015-04-23 20:24:45

+0

以2500萬次迭代的原始基準顯示'ToString()'大約快7%。框架4.5.1,就像我說的,粗糙(但可測量)。 – andleer 2015-04-23 20:40:03