为什么这种隐式使用ToString()不会导致异常?

时间:2017-01-26 14:43:19

标签: c# .net

我已经创建了一个简单的例子来提出这个问题。

以下代码编译并运行:

// Setup ONCE
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 9999);

// Call MANY TIMES to get next random number 
dis(gen);
dis(gen);
dis(gen);

此代码编译但会抛出运行时NullReference异常。

static void Main(string[] args)
{
    string bigString, littleString;
    littleString = null;
    bigString = "word " + littleString + " word";
}

为什么第一个代码没有抛出类似的异常?我本以为,为了将它连接到其他字符串,会隐含使用ToString(),此时它会遇到与第二段代码相同的基本问题。

3 个答案:

答案 0 :(得分:8)

第一个代码段根本不会调用ToString。它调用string.Concat(string, string),它在其实现中处理null值,就好像它们是空字符串一样。它不需要调用ToString将该参数转换为string(无论是null还是string),因为它已经是string 。 (如果不是一个ToString,那么它需要在其上调用null,但只有当它是不是<portlet:namespace/>)。

答案 1 :(得分:3)

这就是String.Concat的工作原理。运算符+ (对于字符串值)使用string.Concatnull字符串替换为空字符串。因此,对于空值,字符串连接中没有对ToString的隐式调用。

在您的第二个代码段中,您明确地在空值上调用ToString,因此是异常。

How to: Concatenate Multiple Strings (C# Programming Guide)

  

在字符串连接操作中,C#编译器处理null   字符串与空字符串相同,但不转换该值   原始的空字符串。

7.7.4 Addition operator

  

binary +运算符在一个或两个时执行字符串连接   操作数的类型为字符串。

     

如果字符串连接的操作数为null,则替换空字符串。否则,任何非字符串参数都将转换为其   通过调用虚拟ToString方法表示字符串   继承自类型对象。

答案 2 :(得分:1)

在字符串连接操作中,C#编译器将空字符串视为空字符串,但它不会转换原始空字符串的值。

https://msdn.microsoft.com/en-us/library/ms228504.aspx