简体   繁体   English

在这种情况下,为什么整数转换为字符串?

[英]Why is the integer converted to string in this case?

What is happening below? 下面发生了什么?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class DotNetPad
{
    public static void Main(string[] args)
    {
        int i = 10;
        string k = "Test";
        Console.WriteLine(i+k);
        Console.WriteLine(k+i);
    }
}

i is being converted to string in both cases. 在这两种情况下i都被转换为字符串。 I am confusing myself with the idea of operator precedence (although this example doesn't show much of that) and evaluation direction. 我对运算符优先级的概念感到困惑(虽然这个例子没有显示出很多)和评估方向。 Sometimes evaluation happens from left-to-right or vice versa. 有时评估从左到右进行,反之亦然。 I don't exactly know the science of how the expression is evaluated... 我不完全了解表达式如何评估的科学...

Why is i converted to string in the above example, and not actually giving a compilation error? 为什么i在上面的例子中转换为字符串,而不是实际给出编译错误?

From the C# spec - section 7.7.4 Addition operator: 从C#规范 - 第7.7.4节添加运算符:

String concatenation : 字符串连接

 string operator +(string x, string y); string operator +(string x, object y); string operator +(object x, string y); 

The binary + operator performs string concatenation when one or both operands are of type string. 一个或两个操作数的类型为字符串时,binary +运算符执行字符串连接。 If an operand of string concatenation is null, an empty string is substituted. 如果字符串连接的操作数为null,则替换空字符串。 Otherwise, any non-string argument is converted to its string representation by invoking the virtual ToString method inherited from type object. 否则,通过调用从类型对象继承的虚拟ToString方法,将任何非字符串参数转换为其字符串表示形式。 If ToString returns null, an empty string is substituted. 如果ToString返回null,则替换空字符串。

I am confusing myself with the idea of operator precedence and evaluation direction. 我对运营商优先级和评估方向的想法感到困惑。

No, you are not. 不,你不是。 That is frequently confused, yes, but that is not the thing you are confusing because neither precedence nor order of evaluation is relevant to the question of whether the integer is converted to a string, or why it is legal to add an integer to a string. 这经常被混淆,是的,但这不是你困惑的事情,因为评估的优先级和顺序都整数是否转换为字符串的问题相关 ,或者为什么将整数添加到字符串是合法的。

To first unconfuse you on the point you claim to be confused on, the rules are quite simple: 首先要让您对自己困惑的事情不以为然,规则很简单:

  • expressions are parenthesized according to operator precedence and associativity. 表达式根据运算符优先级和关联性括起来。
  • subexpressions are evaluated in left-to-right order. 子表达式按从左到右的顺序进行评估。

That's all you need to know to get it right. 这就是你需要知道才能做到的。 Suppose Q() returns an object that has an indexer with a setter, and the other methods all return integers: 假设Q()返回一个带有setter的索引器的对象,其他方法都返回整数:

Q()[R()] = A() * B() + C() / D();

That is parenthesized according to precedence and associativity: 根据优先级和关联性括起来:

Q()[R()] = ( ( A() * B() ) + ( C() / D() ) );

And now every subexpression is evaluated left-to-right. 现在, 每个子表达式都是从左到右进行评估的。 Every subexpression , including subexpressions that themselves have subexpressions. 每个子表达式 ,包括本身都有子表达式的子表达式。 So this is equivalent to the program: 所以这相当于程序:

var q = Q(); 
var r = R(); 
var a = A(); 
var b = B(); 
var t1 = a * b; 
var c = C();
var d = D();
var t2 = c / d;
var t3 = t1 + t2;

and finally the index setter on q is called with index r and value t3. 最后用索引r和值t3调用q上的索引setter。

Notice that every subexpression to the left is evaluated before every subexpression to the right. 请注意, 每个子表达式左边是每个子表达式向右前评估。 A() * B() is left of C() / D() , so it happens first. A() * B()留在C() / D() ,所以它首先发生。

This has nothing whatsoever to do with your question. 这与你的问题没有任何关系。 Your question is based on a misunderstanding. 你的问题是基于误解。

I want to know why i is converted to string in the above example, and not actually giving a compilation error 我想知道为什么我在上面的例子中转换为字符串,并没有实际给出编译错误

There's your misunderstanding. 这是你的误解。 i is not being converted to string. i 没有被转换为字符串。 It is being converted to object . 它正在转换为object Your program is exactly equivalent to: 您的计划完全等同于:

   int i = 10;
   string k = "Test";
   string t1 = System.String.Concat((object)i, (string)k);
   Console.WriteLine(t1);
   string t2 = System.String.Concat((string)k, (object)i);
   Console.WriteLine(t2);

As you can see, there is no conversion from i to string in the first place. 如您所见,首先没有从i转换为字符串。 i is converted to object via a boxing conversion and then passed to the String.Concat method. i通过装箱转换转换为对象,然后传递给String.Concat方法。 That method then calls object.ToString() on the boxed integer. 然后该方法在盒装整数上调用object.ToString()

So that deals with the first half of: 因此,处理上半部分:

I want to know why i is converted to string in the above example, and not actually giving a compilation error 我想知道为什么我在上面的例子中转换为字符串,并没有实际给出编译错误

The second half is: why is there no compilation error? 下半部分是:为什么没有编译错误?

Why should there be a compilation error? 为什么会出现编译错误? The C# specification says that you can add any string to any object, or any object to any string. C#规范说你可以将任何字符串添加到任何对象,或任何对象添加到任何字符串。 An int is an object, and therefore you can add it to a string. int是一个对象,因此您可以将其添加到字符串中。

In both cases, you've got the + operator with the string as one of the operands. 在这两种情况下,你已经得到了+运算符与字符串作为一个操作数。 There are no overloaded user-defined operators involved, so the compiler will use both of those as string concatenation situations. 没有涉及重载的用户定义运算符,因此编译器将使用这两者作为字符串连接情况。

As far as I'm aware, the C# compiler will only not use string concatenation for a scenario of x + y where either x or y is a string expression at compile-time if there's a user-defined overload, eg the XName operator +(XNamespace, string) operator. 据我所知,C#编译器将只不使用字符串连接为一个场景x + y ,其中无论是 xy是一个string在编译时表达,如果有一个用户定义的过载,例如XName operator +(XNamespace, string)运算符。

Actually the "+" operator is for concatenation. 实际上“+”运算符用于连接。 Making concatenation between an int and string will give a string (with automatically cast int to string) 在int和string之间进行连接将给出一个字符串(自动将int转换为字符串)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM