int没有显式转换的字符串?

时间:2013-09-10 15:07:03

标签: c# tostring

我有一个简单的问题,但我很惊讶。

此代码有效:

int itemID = 1;
string dirPath = @"C:\" + itemID + @"\abc";

在这种情况下,我为什么不必itemID.ToString()

6 个答案:

答案 0 :(得分:13)

来自MSDN

  

当一个或两个操作数的类型为字符串时,binary +运算符执行字符串连接。如果字符串连接的操作数为null,则替换空字符串。否则,通过调用从类型对象继承的虚拟ToString方法,将任何非字符串参数转换为其字符串表示形式。如果ToString返回null,则替换空字符串。

根据其他答案中的一些评论,扩展我的答案......

这个过程不仅仅是“语法糖”或方便。它是一个名为Operator Overloading的核心C#语言特性的结果。在+运算符和String +重载的情况下,提供重载作为抽象String类的内部的手段,这是良好设计原则的核心基础。 + String Overload通过确保它永远不会返回空值来提供类型安全性,而是为任何无法使用.ToString()方法转换的操作数返回空字符串。但是,即使自定义复杂类型(不仅仅是基元)也可以添加到字符串中,假设它们具有.ToString()重载,而不知道任何不同的String类型的实现。

运算符重载是一种主要语言功能,更多人应该学会利用它的强大功能。

答案 1 :(得分:8)

字符串连接中的

+被转换为string.Concat调用,该调用在每个对象上内部调用无参数ToString

string.Concate Method - MSDN

  

该方法通过调用the来连接args中的每个对象   该对象的无参数ToString方法;它没有添加任何   分隔符。

编辑:

以下是ILSpy中的内容 enter image description here

答案 2 :(得分:6)

+运算符有许多重载。其中三个如下:

  

operator +(string a,string b)

     

operator +(string a,object b)

     

operator +(对象a,字符串b)

您的代码正在使用运算符的第二个重载。

该运算符在被确定为匹配后,将其转换为对string.Concat的调用,该调用可以将任意数量的对象(类型为object)作为其参数。

string.Concat的定义中,它将在所有参数上调用ToString(在首先检查它们之后)以获取它们的字符串值,这就是将要连接的内容。

由于所有这一切,您始终可以使用字符串连接任何对象,并使用该对象的ToString方法进行编译和执行。

答案 3 :(得分:1)

因为它是由编译器自动完成的。

基本上:

  string a = "abc" + 1; 

编译为:

  string a = string.Concat((object)"abc", (object)1);

这仅仅是语法糖。 虽然我个人不希望自动转换。

Concat的参考: http://msdn.microsoft.com/en-us/library/kbseaaft.aspx

答案 4 :(得分:0)

这是一种语言功能。在使用ToString()运算符进行字符串连接时,会在内部调用+

这个的根本原因仅仅是方便(并且可能由于ToString()调用较少而增加了可读性,但它也可能诱使你认为对象是一个字符串,实际上它可以是任何东西)显影剂。

对于C#,可能采用了Java的行为,这是相同的。可能有趣的是,问一问为什么这首先是在Java中引入的。

答案 5 :(得分:0)

一个非常有趣的问题。

让我们看一下你的例子的IL代码:

 ldstr     "C:\\"
 ldloc.0
 box       int
 ldstr     "\\abc"
 call      string System.String.Concat(object, object, object)

后面的被调用函数是System.String.Concat,它带有3个对象!

让我们深入了解.NET源代码:

public static String Concat(Object arg0, Object arg1, Object arg2) {
        Contract.Ensures(Contract.Result<String>() != null);
        Contract.EndContractBlock();

        if (arg0 == null)
        { 
            arg0 = String.Empty; 
        }

        if (arg1==null) {
            arg1 = String.Empty;
        }

        if (arg2==null) {
            arg2 = String.Empty; 
        } 
           return Concat(arg0.ToString(), arg1.ToString(), arg2.ToString());
   }  

当你看到ToString()它会被召唤但稍后会被召唤出来!这对微软的家伙来说非常令人印象深刻!