Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 关于NullReferenceException的混淆_C#_Arrays_Nullreferenceexception - Fatal编程技术网

C# 关于NullReferenceException的混淆

C# 关于NullReferenceException的混淆,c#,arrays,nullreferenceexception,C#,Arrays,Nullreferenceexception,据我所知,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()); 因此,让我们假设以下情况。我声明了一个实例来实例化一

据我所知,
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
然后我在数组的任何元素上调用Console.WriteLine(),而不实例化Foos本身。因此,在本例中,我们有一个Foo数组,数组中的每个Foo都是
null
,因此对Console.WriteLine()的调用应该导致抛出
NullReferenceException
,对吗?但问题是如果你这样称呼它

Console.WriteLine(foos[0])
Console.WriteLine(foos[0].ToString())
除了控制台窗口中编写的
环境。换行符
之外,什么都不会发生,但是如果您这样调用它

Console.WriteLine(foos[0])
Console.WriteLine(foos[0].ToString())
它实际上抛出了一个
NullReferenceException
。这两个电话有什么区别?我的意思是,在第一个示例中,我没有显式地调用
ToString()
,但Console.WriteLine()不应该隐式地调用它吗?在第一种情况下,如何不抛出
NullReferenceException

那么这两个对Console.WriteLine()的调用是相同的,对吗

Foo foo = new Foo();

Console.WriteLine(foo); // This is same as the one bellow 
Console.WriteLine(foo.ToString());
不可以。因为
Console.WriteLine
不对空引用调用
ToString
——它只使用空字符串。它自己检测到了这一点

《公约》明确规定:

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

没有调用
ToString
,就没有
NullReferenceException

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

object value = null;
string text = string.Format("Value: '{0}'", value);
文本设置为
值:'

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

因此
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());
}
在上面的行中,因为它是空的,所以根据行终止符将被写入,而没有其他内容。我假设首先检查对象是否为null,然后写入行终止符,否则调用对象上的
ToString()
方法。鉴于

Console.WriteLine(obj.ToString())
正在对null调用ToString方法,这是一个异常