string.Format 如何处理空值?
Posted
技术标签:
【中文标题】string.Format 如何处理空值?【英文标题】:How does string.Format handle null values? 【发布时间】:2012-11-07 19:04:09 【问题描述】:在下面的代码中,为什么两个string.Format
调用的行为方式不同?第一个不抛出异常,但第二个抛出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);
有人可以帮我理解这两者之间的区别吗?
【问题讨论】:
您可能在第二个示例中遇到了params
override,String.Format
测试了数组在继续迭代集合和插入值之前是否已填充。
@BradChristie 你应该把它写成答案。
【参考方案1】:
我在这里猜测,但它看起来是你打哪个重载呼叫的区别; 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
的工作方式是您可以在调用中将either 每个值作为新对象传递或值的数组。也就是说,下面是one in the same:
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();
【讨论】:
另外:试试string.Format("Occurred: 0", (object[])null)
和string.Format("Occurred: 0", (object)null)
之间的区别。还有一种可能性:string.Format("Occurred: 0", new[] (object)null, )
。我猜,问题只发生在第一种情况下。【参考方案2】:
在您的第一个示例中,您点击了Format(String, Object)
,反汇编后看起来像这样:
public static string Format(string format, object arg0)
return Format(null, format, new object[] arg0 );
注意周围的new object[]
。
第二个,您显然使用了Format(string, object[])
,至少这是我执行相同测试时调用的那个。拆开看是这样的:
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,这就是你的问题,就在那里!第一次调用是将其包装在一个新数组中,因此它不为空。由于调用的是 Format()
的特定实例,因此显式传入 null 并不会让它这样做。
【讨论】:
【参考方案3】:如果您使用插值字符串($"",另一种格式化方式),则 null 将被忽略,跳过。所以
string nullString = null;
Console.WriteLine($"This is a 'nullString' in a string");
将产生:“这是一个字符串中的''”。当然,您可以在 null 的情况下使用 null 合并运算符来生成所需的输出:
string nullString = null;
Console.WriteLine($"This is a 'nullString ?? "nothing"' in a string");
【讨论】:
【参考方案4】:第一个调用被解析为对 Format(object) 的调用,而第二个调用被解析为对 Format(object[]) 的调用。这些不同的重载对空参数的处理方式不同。
重载分辨率描述为here。相关部分是对于 Format 的第二次调用,Format(params object[]) 的重载被扩展为 Format(object[]),它比 Format(object) 更受欢迎。字面量 null 既是 object[] 又是 object,但 object[] 更具体,因此被选中。
【讨论】:
【参考方案5】:有以下两个区别:
在这里,分配了 Null 值。
Exception e = null;
string msgOne = string.Format("An exception occurred: 0", e);
这里,Null 值不能以字符串格式读取,这意味着类型转换错误。
string msgTwo = string.Format("Another exception occurred: 0", null);
我给你一个简单的例子: 此处,您无法将 NULL 值读取为字符串格式。
string str = null.toString();
【讨论】:
以上是关于string.Format 如何处理空值?的主要内容,如果未能解决你的问题,请参考以下文章