59

如果我运行此代码:

Console.WriteLine( String.Format( "{0}", null ) );

我得到一个ArgumentNullException,但如果我运行这段代码:

String str = null;
Console.WriteLine( String.Format( "{0}", str ) );

它运行得很好,输出是一个空字符串。

现在这两块看起来和我一样——它们都传递了一个空引用,String.Format()但行为却不同。

在这里如何识别不同的行为?

4

1 回答 1

76

只需反编译代码即可了解发生了什么。

string.Format("{0}", null)

调用最具体的适用重载,即string.Format(string, object[]).

的重载string.Format是:

Format(String, Object)
Format(String, Object[])
Format(IFormatProvider, String, Object[])
Format(String, Object, Object)
Format(String, Object, Object, Object)

希望很明显为什么最后三个选项无效。

为了确定使用前两个中的哪一个,编译器将转换 from nulltoObject与转换 from nullto进行比较Object[]。转换为Object[]被认为是“更好”,因为存在从Object[]to的转换Object,但反之则不然。这与如果我们有相同的逻辑:

Foo(String)
Foo(Object)

并打电话Foo(null),它会接Foo(String)

所以你的原始代码相当于:

object[] values = null;
string.Format("{0}", values);

在这一点上,希望您期望-根据ArgumentNullException文档。

于 2012-12-14T11:16:19.563 回答