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

本文关键字:转换 字符串 整数 这种情况下 为什么 | 更新日期: 2023-09-27 18:32:51

下面发生了什么?

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都将转换为字符串。我对运算符优先级(尽管此示例没有显示太多(和评估方向的想法感到困惑。有时评估从左到右进行,反之亦然。我不完全知道如何评估表达式的科学......

为什么在上面的示例中i转换为字符串,而不是实际上给出编译错误?

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

来自 C# 规范 - 第 7.7.4 节 加法运算符:

字符串连接

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

二进制 + 运算符在其中一个或两个时执行字符串连接 操作数的类型为字符串。如果字符串串联的操作数是 null,则替换空字符串。否则,任何非字符串 参数通过调用 从类型对象继承的虚拟 ToString 方法。如果到字符串 返回 null,替换空字符串。

我对运算符优先级和评估方向的想法感到困惑。

不,你不是。是的,这经常被混淆,但这不是您混淆的事情,因为计算的优先级和顺序都与整数是否转换为字符串的问题无关,或者为什么将整数添加到字符串是合法的。

首先要让你在你声称感到困惑的问题上感到困惑,规则非常简单:

  • 表达式根据运算符优先级和关联性用括号括起来。
  • 子表达式按从左到右的顺序计算。

这就是您需要知道的才能正确处理的全部内容。假设 Q(( 返回一个对象,该对象具有带有 setter 的索引器,而其他方法都返回整数:

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

根据优先级和关联性用括号括起来:

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

现在,每个子表达式都从左到右计算。每个子表达式,包括本身具有子表达式的子表达式。所以这相当于程序:

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;

最后,Q 上的索引设置器被调用,索引为 R 和值 T3。

请注意,左侧的每个子表达式在右侧的每个子表达式之前计算。 A() * B()C() / D()的左边,所以它首先发生。

这与你的问题没有任何关系。你的问题是基于误解。

想知道为什么在上面的例子中我被转换为字符串,而不是实际上给出编译错误

这是你的误会。 i转换为字符串。它正在转换为object。您的程序完全等效于:

   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);

如您所见,首先没有从i到字符串的转换。 i通过装箱转换转换为对象,然后传递给 String.Concat 方法。 然后,该方法对带框的整数调用object.ToString()

因此,这涉及以下前半部分:

想知道为什么在上面的例子中我被转换为字符串,而不是实际上给出编译错误

后半部分是:为什么没有编译错误?

为什么会出现编译错误?C# 规范规定,您可以将任何字符串添加到任何对象,或将任何对象添加到任何字符串。int 是一个对象,因此您可以将其添加到字符串中。

在这两种情况下,您都有 + 运算符,并将字符串作为操作数之一。不涉及重载的用户定义运算符,因此编译器将使用这两个运算符作为字符串连接情况

据我所知,C# 编译器只会在x + y的情况下使用字符串串联,其中 xy 在编译时是string表达式,如果有用户定义的重载,例如 XName operator +(XNamespace, string) 运算符。

实际上,"+"运算符用于串联。在 int 和字符串之间进行连接将得到一个字符串(自动将 int 转换为字符串(