如何string.Format处理空值?

在下面的代码中,为什么两个string.Format调用的行为不一样? 在第一个中,没有抛出exception,但是在第二个抛出了ArgumentNullException

 static void Main(string[] args) { Exception e = null; string msgOne = string.Format("An exception occurred: {0}", e); string msgTwo = string.Format("Another exception occurred: {0}", null); } 

有人能帮我理解两者的区别吗?

我在这里猜测,但它看起来是你打的重载呼叫的差异。 String.Format有多个重载,它只是你打的。

在第一个例子中,这是有意义的,你正在String.Format(string,object)

在第二个例子中,通过提供null你最有可能击中String.Format(string,params object[]) ,根据文档,这将引发一个ArgumentNullException

格式或参数为空。

如果您正在运行.NET4,请尝试使用命名参数:

 String.Format("Another exception occured: {0}", arg0: null); 

为什么它碰到params object[]重载? 可能是因为null不是一个对象,而且params工作方式是可以将每个值作为新的对象传递给它, 或者传递一个值作为数组。 也就是说,下面是一个一样的 :

 String.Format("Hello, {0}! Today is {1}.", "World", "Sunny"); String.Format("Hello, {0}! Today is {1}.", new Object[]{ "World", "Sunny" }) 

所以它将您的声明呼叫翻译成以下内容:

 String format = "Another exception occured: {0}"; Object[] args = null; String.Format(format, args); // throw new ArgumentNullException(); 

在你的第一个例子中,你正在打击Format(String, Object) ,看起来像这样反汇编:

  public static string Format(string format, object arg0) { return Format(null, format, new object[] { arg0 }); } 

注意那个new object[]

第二个,你显然正在使用Format(string, object[])用法,至less这是一个被调用时,我执行相同的testing。 拆解,看起来像这样:

  public static string Format(string format, params object[] args) { return Format(null, format, args); } 

所以所有这些实际上都被Format(IFormatProvider, string, object[]) 。 很酷,让我们看看那里的头几行:

 public static string Format(IFormatProvider provider, string format, params object[] args) { if ((format == null) || (args == null)) { throw new ArgumentNullException((format == null) ? "format" : "args"); } ... } 

welp,这是你的问题,在那里! 第一个调用将它包装在一个新的数组中,所以它不是null。 由于正在调用的Format()的具体实例,显式传入null并不会这样做。

第一个调用被parsing为对Format(object)的调用,而第二个调用被parsing为对Format(object [])的调用。 这些不同的重载处理空参数是不同的。

这里描述的是重载分辨率。 相关部分是对Format的第二次调用,Format(params object [])的重载被扩展为Format(object []),这是Format(object)的首选。 字面null既是一个对象[]和一个对象,但对象[]更具体,所以select。

有以下两点不同之处:

  1. 在这里,分配空值。

     Exception e = null; string msgOne = string.Format("An exception occurred: {0}", e); 
  2. 在这里,空值不能以string格式读取,这意味着types转换错误。

     string msgTwo = string.Format("Another exception occurred: {0}", null); 

我给你简单的例子:在这里,你不能读取NULL值作为string格式。

 string str = null.toString();