字符串和整数,隐式和显式

有一个同事问我这个问题,在我脑子里迷茫的状态我没有答案:

你为什么这样做:

string ham = "ham " + 4; 

但不是:

 string ham = 4; 

如果在连接时存在字符串转换的隐式转换/操作,为什么在指定为字符串时不一样? (当然没有做一些运算符重载)

连接编译器时,将语句"ham" + 4转换为对String.Concat的调用,后者接受两个object参数,因此将值4装箱,然后调用ToString

对于赋值,没有从intstring隐式转换,因此您无法在不显式转换string情况下将4分配给string

换句话说,编译器处理两个赋值的方式非常不同,尽管它们在C#中看起来非常相似。

二进制+运算符是为数字和字符串类型预定义的。 对于数字类型,+计算其两个操作数的总和。 当一个或两个操作数都是string类型时,+连接操作数的字符串表示。

参考

赋值运算符(=)将其右侧操作数的值存储在由其左侧操作数表示的存储位置,属性或索引器中,并将该值作为结果返回。 操作数必须是相同的类型(或者右操作数必须可以隐式转换为左操作数的类型)。

参考

进行连接时没有隐式转换。 字符串连接解析为String.Concat调用,该调用具有带对象的重载。 正是这个重载执行(显式)转换为字符串。

第一个表达式右侧的值是一个字符串,而第二个表达式右侧的值不是。 连接在第一个场景中提供了魔力,其中赋值没有做任何特殊的事情。 在第二种情况下,任务继续发挥愚蠢。

表达方式

 "ham " + 4 

基于字符串类型和加法运算符的组合强制将4隐式转换为字符串。 具体来说,它是“+”运算符的质量,当执行运算符重载时,您可以手动实现相同类型的事物。

一个类似且不太明显的例子是:

long myNumber = Int64.MaxValue – 1;

在这种情况下,“1”应该被评估为32位整数,但它是隐式转换的。 您可以查看C#语言规范第6.1节,了解编译器支持的隐式转换的详尽列表。

编辑:要清楚,我引用的语言规范部分列出了编译器支持的隐式转换,而像“+”这样的运算符可以有自己支持的转换。