string = string + int:幕后是啥?

Posted

技术标签:

【中文标题】string = string + int:幕后是啥?【英文标题】:string = string + int: What's behind the scenes?string = string + int:幕后是什么? 【发布时间】:2011-03-24 20:08:08 【问题描述】:

在 C# 中,您可以隐式连接一个字符串,比如说一个整数:

string sth = "something" + 0;

我的问题是:

    为什么,假设您可以隐式连接字符串和 int,C# 不允许像这样初始化字符串:

    string sth = 0; // Error: Cannot convert source type 'int' to target type 'string'
    

    C# 如何将 0 转换为字符串。是0.ToString() 还是(string)0 还是别的什么?

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

【问题讨论】:

我特别喜欢你问“如何找到上一个问题的答案?” 【参考方案1】:

它编译为对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 或 Reflector(在 IL 或 C# 中没有优化)查看 + 行编译成什么。

【讨论】:

SLaks 是正确的,但要阐述 OP 的问题:1)“+”是字符串和对象之间的重载运算符 2)是的,最终调用 .ToString() 3)反射器 另见this answer。 抛出一些 IL 可能对那些懒惰的程序员节省一点时间很有用... (我们所有人...) 看来编译器并没有优化这个;在 JetBrains 上有一个有趣的辩论:devnet.jetbrains.com/thread/266160【参考方案2】:

这在 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);

二进制文件的这些重载 + 运算符执行字符串连接。 如果字符串连接的操作数 为 null,则为空字符串 代替。否则,任何非字符串 参数被转换为它的字符串 通过调用虚拟表示 ToString 方法继承自类型 目的。如果 ToString 返回 null,则 替换空字符串。

指定如何将整数转换为字符串。

结果:

字符串拼接的结果 运算符是一个字符串,由 左操作数的字符 其次是字符 右操作数。字符串 连接运算符从不返回 a 空值。

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

【讨论】:

"abc" + 123 是否导致 123 被装箱? "abc" + 123.ToString() 会不会更高效? @andleer:它是特定于实现的,但是是的,确实如此......所以理论上,123.ToString() 会更有效,但 JIT 可能会意识到这种模式。跨度> 经过 2500 万次迭代的粗略基准显示 ToString() 大约快 7%。框架 4.5.1,就像我说的那样,粗糙(但可衡量)。 c# 4 中是否引入了此功能?我的意思是它在以前的 c# 版本中不存在吗? @Dhanajay:什么,非字符串的字符串转换为连接?不,它一直存在。

以上是关于string = string + int:幕后是啥?的主要内容,如果未能解决你的问题,请参考以下文章

怎么把string转换成int

int数组 如何转换为 string

c++ int转化为string 类型

String 如何转换成int比较大小

c++ string int

判断string可否转换为int