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

时间:2021-12-21 03:43:46

Had a coworker ask me this, and in my brain befuddled state I didn't have an answer:

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

Why is it that you can do:

你为什么这样做:

string ham = "ham " + 4;

But not:

string ham = 4;

If there's an implicit cast/operation for string conversion when you are concatenating, why not the same when assigning it as a string? (Without doing some operator overloading, of course)

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

5 个解决方案

#1


When concatenating the compiler turns the statement "ham" + 4 into a call to String.Concat, which takes two object parameters, so the value 4 is boxed and then ToString is called on that.

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

For the assignment there is no implicit conversion from int to string, and thus you cannot assign 4 to a string without explicitly converting it.

对于赋值,没有从int到string的隐式转换,因此您无法在不显式转换字符串的情况下将4分配给字符串。

In other words the two assignments are handled very differently by the compiler, despite the fact that they look very similar in C#.

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

#2


Binary + operators are predefined for numeric and string types. For numeric types, + computes the sum of its two operands. When one or both operands are of type string, + concatenates the string representations of the operands.

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

Reference

The assignment operator (=) stores the value of its right-hand operand in the storage location, property, or indexer denoted by its left-hand operand and returns the value as its result. The operands must be of the same type (or the right-hand operand must be implicitly convertible to the type of the left-hand operand).

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

Reference

#3


There is no implicit conversion when doing concatenation. String concatenation resolves down to a String.Concat call, which has an overload which takes Objects. It is this overload which performs an (explicit) conversion to string.

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

#4


The value of the righthand side of the first expression is a string, while the value of the righthand side of the second expression is not. The concatonation is providing the magic in the first scenario, where the assignment isn't doing anything special. In the second scenario, the assignment continues to play dumb.

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

#5


The expression

"ham " + 4 

Forces an implicit conversion of 4 to a string based on the combination of a string type and the addition operator. Specifically it's a quality of the "+" operator, and when doing operator overloading you can manually implement the same type of thing.

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

A similar and less obvious example would be:

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

long myNumber = Int64.MaxValue - 1;

long myNumber = Int64.MaxValue - 1;

In this case "1" should be evaluated as a 32-bit integer but it is implicitly converted. You can check the C# language spec section 6.1 for an exhaustive list of implicit conversions supported by the compiler.

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

edit: to be clear, the language spec section i referred to lists implicit conversions supported by the compiler, while operators like "+" can have their own supported conversions.

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

#1


When concatenating the compiler turns the statement "ham" + 4 into a call to String.Concat, which takes two object parameters, so the value 4 is boxed and then ToString is called on that.

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

For the assignment there is no implicit conversion from int to string, and thus you cannot assign 4 to a string without explicitly converting it.

对于赋值,没有从int到string的隐式转换,因此您无法在不显式转换字符串的情况下将4分配给字符串。

In other words the two assignments are handled very differently by the compiler, despite the fact that they look very similar in C#.

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

#2


Binary + operators are predefined for numeric and string types. For numeric types, + computes the sum of its two operands. When one or both operands are of type string, + concatenates the string representations of the operands.

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

Reference

The assignment operator (=) stores the value of its right-hand operand in the storage location, property, or indexer denoted by its left-hand operand and returns the value as its result. The operands must be of the same type (or the right-hand operand must be implicitly convertible to the type of the left-hand operand).

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

Reference

#3


There is no implicit conversion when doing concatenation. String concatenation resolves down to a String.Concat call, which has an overload which takes Objects. It is this overload which performs an (explicit) conversion to string.

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

#4


The value of the righthand side of the first expression is a string, while the value of the righthand side of the second expression is not. The concatonation is providing the magic in the first scenario, where the assignment isn't doing anything special. In the second scenario, the assignment continues to play dumb.

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

#5


The expression

"ham " + 4 

Forces an implicit conversion of 4 to a string based on the combination of a string type and the addition operator. Specifically it's a quality of the "+" operator, and when doing operator overloading you can manually implement the same type of thing.

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

A similar and less obvious example would be:

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

long myNumber = Int64.MaxValue - 1;

long myNumber = Int64.MaxValue - 1;

In this case "1" should be evaluated as a 32-bit integer but it is implicitly converted. You can check the C# language spec section 6.1 for an exhaustive list of implicit conversions supported by the compiler.

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

edit: to be clear, the language spec section i referred to lists implicit conversions supported by the compiler, while operators like "+" can have their own supported conversions.

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