如果一位同事问我这个问题,并且在我脑子里迷茫的状态我没有答案:
为什么你可以这样做:
string ham = "ham " + 4;
但不是:
string ham = 4;
如果连接时存在字符串转换的隐式转换/操作,为什么将分配为字符串时不一样? (当然没有做一些运算符重载)
答案 0 :(得分:19)
当连接编译器时,将语句"ham" + 4
转换为对String.Concat
的调用,这需要两个object
个参数,因此值4
被加框,然后{{1调用它。
对于分配,没有从ToString
到int
的隐式转换,因此您无法在未明确转换string
的情况下将4
分配给string
。
换句话说,编译器对两个赋值的处理方式有很大不同,尽管它们在C#中看起来非常相似。
答案 1 :(得分:4)
二进制+运算符是预定义的 数字和字符串类型。对于数字 类型,+计算它们的总和 操作数。当一个或两个操作数 是字符串类型,+连接 字符串表示 操作数。
赋值运算符(=)存储 它的右手操作数的值 存储位置,属性或索引器 用左手操作数表示 返回值作为结果。该 操作数必须是相同的类型(或 必须是右手操作数 隐式可转换为类型 左手操作数。)
答案 2 :(得分:2)
进行连接时没有隐式转换。字符串连接解析为String.Concat调用,该调用具有带对象的重载。正是这个重载执行(显式)转换为字符串。
答案 3 :(得分:0)
第一个表达式右侧的值是一个字符串,而第二个表达式的右侧值不是。连接在第一个场景中提供了魔力,其中赋值没有做任何特殊的事情。在第二种情况下,作业继续发挥愚蠢。
答案 4 :(得分:0)
表达式
"ham " + 4
根据字符串类型和加法运算符的组合强制将4隐式转换为字符串。具体来说,它是“+”运算符的质量,当执行运算符重载时,您可以手动实现相同类型的事物。
一个类似且不太明显的例子是:
long myNumber = Int64.MaxValue - 1;
在这种情况下,“1”应该被评估为32位整数,但它是隐式转换的。您可以查看C#语言规范第6.1节,了解编译器支持的隐式转换的详尽列表。
编辑:要清楚,我所提到的语言规范部分列出了编译器支持的隐式转换,而像“+”这样的运算符可以有自己支持的转换。