string = string + int:幕后是什么?

Dar*_*iak 51 c# string integer casting

在C#中,你可以隐式地连接一个字符串,让我们说一个整数:

string sth = "something" + 0;
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 为什么,假设您可以隐式地连接字符串和int,C#不允许初始化字符串,如下所示:

    string sth = 0; // Error: Cannot convert source type 'int' to target type 'string'
    
    Run Code Online (Sandbox Code Playgroud)
  2. C#如何将0转换为字符串.它是0.ToString()或者(string)0还是其他什么东西?

  3. 如何找到上一个问题的答案?

SLa*_*aks 54

它编译成一个调用String.Concat(object, object),如下所示:

string sth = String.Concat("something", 0);
Run Code Online (Sandbox Code Playgroud)

(注意,这个特定的行实际上会被编译器优化掉)

此方法定义如下:(取自.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());
    }
Run Code Online (Sandbox Code Playgroud)

(这个电话String.Concat(string, string))


要发现这一点,您可以使用ildasm或反射器(在IL或C#中没有优化)来查看该+行编译的内容.

  • SLaks是正确的,但要解释OP的问题:1)"+"是字符串和对象之间的重载运算符2)是的,.ToString()最终被称为3)Reflector (6认同)

Jon*_*eet 22

这在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);
Run Code Online (Sandbox Code Playgroud)

二进制+运算符的这些重载执行字符串连接.如果字符串连接的操作数为null,则替换空字符串.否则,通过调用ToString从类型object继承的虚方法,将任何非字符串参数转换为其字符串表示 形式.如果ToString返回null,则替换空字符串.

这指定了整数如何转换为字符串.

结果如下:

字符串连接运算符的结果是一个字符串,其中包含左操作数的字符,后跟右操作数的字符.字符串连接运算符永远不会返回空值.

执行连接的实际方法是特定于实现的,但正如其他答案中所述,MS实现使用string.Concat.

  • @andleer:它是特定于实现的,但是,它确实......所以理论上,`123.ToString()`会更有效,但是JIT可能知道这种模式. (2认同)