据我所知Console.WriteLine()
(或Console.Write()
)调用对象的ToString()
方法来获取对象的字符串represantation对吗?那么对Console.WriteLine()
的两次调用是否正确?
Foo foo = new Foo();
Console.WriteLine(foo); // This is same as the one bellow
Console.WriteLine(foo.ToString());
所以我们假设以下情况。我声明一个实例化一个Foos数组。
Foo[] foos = new Foo[10]; // After this line all 10 Foos are `null`s
然后我在数组的任何元素上调用Console.WriteLine()而不实例化Foos本身。所以在这种情况下我们有一个Foos数组,数组中的每个Foo都是null
所以调用Console.WriteLine()会导致NullReferenceException
被抛出正确吗?但事情是,如果你这样称呼它
Console.WriteLine(foos[0])
除了在控制台窗口中写入Environment.NewLine
之外没有任何反应,但如果你这样称呼它
Console.WriteLine(foos[0].ToString())
它实际上抛出NullReferenceException
。这两个电话有什么区别?我的意思是在第一个中我没有明确地调用ToString()
但是它不应该被Console.WriteLine()隐式调用吗?如果NullReferenceException
在第一种情况下不被抛出怎么办?
答案 0 :(得分:13)
那么这两个对Console.WriteLine()的调用是否正确?
没有。由于Console.WriteLine
不会在空引用上调用ToString
,因此它只使用空字符串。它会检测到它自己。
documentation明确说明了这一点:
如果value为null,则只写入行终止符。否则,调用ToString方法的值以生成其字符串表示形式,并将结果字符串写入标准输出流。
没有致电ToString
,就没有NullReferenceException
。
string.Format
的行为方式相同。例如:
object value = null;
string text = string.Format("Value: '{0}'", value);
会将text
设置为Value: ''
答案 1 :(得分:5)
Console.WriteLine Method (Object)
如果值为
null
,则仅写入行终止符。否则,调用ToString
value方法以生成其字符串表示形式,并将结果字符串写入标准输出流。
所以Console.WriteLine(obj)
和Console.WriteLine(obj.ToString())
并不完全相同。
还有一些代码:
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());
}
答案 2 :(得分:0)
Console.WriteLine(foos[0])
在上面的行中,因为它是null,因此根据documentation行终止符将被写入,没有别的。我假设它将首先检查对象是否为null然后写行终止符,否则调用对象上的ToString()
方法。而
Console.WriteLine(obj.ToString())
在null上调用ToString方法,这是一个例外。