我已经创建了一个简单的例子来提出这个问题。
以下代码编译并运行:
// 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(),此时它会遇到与第二段代码相同的基本问题。
答案 0 :(得分:8)
第一个代码段根本不会调用ToString
。它调用string.Concat(string, string)
,它在其实现中处理null
值,就好像它们是空字符串一样。它不需要调用ToString
将该参数转换为string
(无论是null
还是string
),因为它已经是string
。 (如果不是一个ToString
,那么它将需要在其上调用null
,但只有当它是不是<portlet:namespace/>
)。
答案 1 :(得分:3)
这就是String.Concat
的工作原理。运算符+
(对于字符串值)使用string.Concat
将null
字符串替换为空字符串。因此,对于空值,字符串连接中没有对ToString
的隐式调用。
在您的第二个代码段中,您明确地在空值上调用ToString
,因此是异常。
How to: Concatenate Multiple Strings (C# Programming Guide)
在字符串连接操作中,C#编译器处理null 字符串与空字符串相同,但不转换该值 原始的空字符串。
binary +运算符在一个或两个时执行字符串连接 操作数的类型为字符串。
如果字符串连接的操作数为null,则替换空字符串。否则,任何非字符串参数都将转换为其 通过调用虚拟ToString方法表示字符串 继承自类型对象。
答案 2 :(得分:1)
在字符串连接操作中,C#编译器将空字符串视为空字符串,但它不会转换原始空字符串的值。