关于NullReferenceException的困惑
本文关键字:NullReferenceException 关于 | 更新日期: 2023-09-27 18:27:58
据我所知,Console.WriteLine()
(或Console.Write()
)调用对象的ToString()
方法来获得对象的字符串表示,对吗?所以这两个呼叫Console.WriteLine()
是一样的,对吧?
Foo foo = new Foo();
Console.WriteLine(foo); // This is same as the one bellow
Console.WriteLine(foo.ToString());
因此,让我们假设以下情况。我声明一个实例化Foo数组。
Foo[] foos = new Foo[10]; // After this line all 10 Foos are `null`s
然后,我在不实例化Foo本身的情况下,对数组的任何元素调用Console.WriteLine()。所以在这种情况下,我们有一个Foo数组,数组中的每个Foo都是null
,所以对Console.WriteLine()的调用应该会导致抛出一个NullReferenceException
,对吗?但问题是,如果你把它称为
Console.WriteLine(foos[0])
除了在控制台窗口中写入Environment.NewLine
之外,什么都没有发生,但如果你像这样调用它
Console.WriteLine(foos[0].ToString())
它实际上抛出一个CCD_ 8。这两个电话有什么区别?我的意思是,在第一个例子中,我不显式调用ToString()
,但Console.WriteLine()不应该隐式调用它吗?在第一种情况下,如何不抛出NullReferenceException
?
所以这两个对Console.WriteLine()的调用是一样的,对吧?
没有。因为Console.WriteLine
不会在null引用上调用ToString
,所以它只使用空字符串。它自己检测到了这一点。
文件明确指出:
如果值为null,则只写入行终止符。否则,将调用值的ToString方法来生成其字符串表示,并将生成的字符串写入标准输出流。
没有对ToString
的调用,就没有NullReferenceException
。
CCD_ 15的行为方式相同。例如:
object value = null;
string text = string.Format("Value: '{0}'", value);
将text
设置为Value: ''
Console.WriteLine方法(对象)
如果值为
null
,则只写入行终止符。否则,将调用值的ToString
方法来生成其字符串表示,并将生成的字符串写入标准输出流。
因此CCD_ 20和CCD_ 21并不完全相同。
还有一点代码:
public virtual void WriteLine(object value)
{
if (value == null)
{
this.WriteLine();
return;
}
IFormattable formattable = value as IFormattable;
if (formattable != null)
{
this.WriteLine(formattable.ToString(null, this.FormatProvider));
return;
}
this.WriteLine(value.ToString());
}
Console.WriteLine(foos[0])
在上面的行中,由于它为null,因此根据文档,将编写行终止符,而不编写其他内容。我假设它将首先检查对象是否为null,然后写入行终止符,否则将调用对象上的ToString()
方法。而
Console.WriteLine(obj.ToString())
正在对null调用ToString方法,这是一个异常。