有一个同事问我这个问题,在我头脑混乱的状态下,我没有答案:
为什么你可以这样做:
string ham = "ham " + 4;
但不是:
string ham = 4;
如果在concatenating时存在字符串转换的隐式转换/操作,为什么在将其分配为字符串时不一样?(当然,不做一些运算符重载)
连接编译器时,编译器会将语句"ham" + 4
转换为对 的调用String.Concat
,该调用带有两个object
参数,因此该值4
被装箱,然后ToString
在其上调用。
对于赋值,没有从int
to的隐式转换string
,因此您不能在不显式转换的情况下分配4
给 a string
。
换句话说,编译器对这两个赋值的处理方式非常不同,尽管它们在 C# 中看起来非常相似。
进行连接时没有隐式转换。字符串连接解析为 String.Concat 调用,该调用具有接受对象的重载。正是这种重载执行了(显式)到字符串的转换。
第一个表达式右边的值是一个字符串,而第二个表达式右边的值不是。连接在第一个场景中提供了魔力,其中任务没有做任何特别的事情。在第二种情况下,作业继续装傻。
表达方式
"ham " + 4
根据字符串类型和加法运算符的组合,强制将 4 隐式转换为字符串。具体来说,它是“+”运算符的一种特性,在进行运算符重载时,您可以手动实现相同类型的东西。
一个类似但不太明显的例子是:
long myNumber = Int64.MaxValue - 1;
在这种情况下,“1”应该被评估为一个 32 位整数,但它是隐式转换的。您可以查看 C# 语言规范第 6.1 节以获取编译器支持的隐式转换的详尽列表。
编辑:要清楚,我提到的语言规范部分列出了编译器支持的隐式转换,而像“+”这样的运算符可以有自己支持的转换。