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:幕后是啥?的主要内容,如果未能解决你的问题,请参考以下文章