2

据我所知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());

因此,让我们假设以下情况。我声明了一个 Foos 数组的实例化。

Foo[] foos = new Foo[10]; // After this line all 10 Foos are `null`s

然后我在数组的任何元素上调用 Console.WriteLine() 而不实例化 Foos 本身。因此,在这种情况下,我们有一个 Foos 数组,并且数组中的每个 Foo 都是null这样,所以对 Console.WriteLine() 的调用应该会导致 aNullReferenceException被抛出,对吗?但问题是,如果你这样称呼它

Console.WriteLine(foos[0])

除了在控制台窗口中写入之外,什么也没有发生,Environment.NewLine但如果你这样称呼它

Console.WriteLine(foos[0].ToString())

它实际上抛出一个NullReferenceException. 这两个调用有什么区别?我的意思是在第一个我没有ToString()显式调用但不应该由 Console.WriteLine() 隐式调用它吗?NullReferenceException在第一种情况下如何不抛出?

4

3 回答 3

13

所以这两个对 Console.WriteLine() 的调用是一样的吗?

不。因为Console.WriteLine 调用ToString空引用 - 它只是使用空字符串。它自己检测到。

文档明确说明了这一点:

如果 value 为 null,则仅写入行终止符。否则,将调用 value 的 ToString 方法以生成其字符串表示形式,并将生成的字符串写入标准输出流。

没有调用 to ToString,就没有NullReferenceException

string.Format行为方式相同。例如:

object value = null;
string text = string.Format("Value: '{0}'", value);

将设置textValue: ''

于 2013-08-15T14:08:50.117 回答
5

Console.WriteLine 方法(对象)

如果值为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());
}
于 2013-08-15T14:09:26.880 回答
0
Console.WriteLine(foos[0])

在上面的行中,因为它是空的,因此根据文档行终止符将被写入,仅此而已。我假设它将首先检查对象是否为空,然后编写行终止符,否则调用ToString()对象上的方法。然而

Console.WriteLine(obj.ToString())

在 null 上调用 ToString 方法,这是一个异常。

于 2013-08-15T14:13:26.420 回答