string.Format如何处理空值?

Mar*_*tin 62 .net c# string.format

在下面的代码中,为什么这两个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);
}
Run Code Online (Sandbox Code Playgroud)

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

Bra*_*tie 50

我在这里猜测,但它看起来是你正在击中的超负荷电话的区别.String.Format有多个重载,它只是你要击中的.

在第一个例子中,你会有意义String.Format(string,object).

在第二个例子中,根据文档提供null你最有可能发生的String.Format(string,params object[])事情ArgumentNullException:

format或args为null.

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

String.Format("Another exception occured: {0}", arg0: null);
Run Code Online (Sandbox Code Playgroud)

为什么会params object[]超载?可能因为null不是对象的方式,以及params工作原理是,你可以通过任何呼叫每个值作为一个新的对象传递给它的值的数组.也就是说,以下是同一个:

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

因此,它将您的语句调用转换为以下内容:

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


tme*_*ser 12

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

 public static string Format(string format, object arg0)
 {
    return Format(null, format, new object[] { arg0 });
 }
Run Code Online (Sandbox Code Playgroud)

注意new object[]那个.

第二个,你显然正在Format(string, object[])使用,至少那是我执行相同测试时被调用的那个.拆卸,看起来像这样:

 public static string Format(string format, params object[] args)
 {
     return Format(null, format, args);
 }
Run Code Online (Sandbox Code Playgroud)

因此,所有这些实际上都得到了帮助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");
    }
...
}
Run Code Online (Sandbox Code Playgroud)

......谢谢,那是你的问题,就在那儿!第一次调用是将它包装在一个新数组中,所以它不是null.由于该Format()调用的特定实例,明确地传入null并不会使它成功.


Ger*_*ard 6

如果您使用内插字符串($"",另一种格式化方式),则忽略、跳过空值。所以

string nullString = null;
Console.WriteLine($"This is a '{nullString}' in a string");
Run Code Online (Sandbox Code Playgroud)

将产生:“这是字符串中的 ''”。当然,您可以在 null 的情况下使用 null 合并运算符来生成所需的输出:

string nullString = null;
Console.WriteLine($"This is a '{nullString ?? "nothing"}' in a string");
Run Code Online (Sandbox Code Playgroud)