2010-08-03 69 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