我正在使用反射器来查看string.format的实现,并且一直在印象中,string.format的过载是1、2和3参数的优化版本,该版本是使用对象数组的方法的。但是,我发现他们在内部创建一个对象数组,然后调用一个对象数组的方法。

1 arg

public static string Format(string format, object arg0)
{
    if (format == null)
    {
        throw new ArgumentNullException("format");
    }
    return Format(null, format, new object[] { arg0 });
}

2 args

public static string Format(string format, object arg0, object arg1)
{
    if (format == null)
    {
        throw new ArgumentNullException("format");
    }
    return Format(null, format, new object[] { arg0, arg1 });
}

3 args

public static string Format(string format, object arg0, object arg1, object arg2)
{
    if (format == null)
    {
        throw new ArgumentNullException("format");
    }
    return Format(null, format, new object[] { arg0, arg1, arg2 });
}

对象数组

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

在内部,它们最终都使用相同的代码,因此使用1、2和3参数版本的速度不比对象数组版本快。

所以我的问题是 - 为什么它们存在?

当您使用带有逗号分离的值列表的对象数组版本时,编译器会自动将参数转换为对象数组,因为params/paramarray关键字本质上是1、2&3版本的作用,因此它们似乎是冗余的。为什么BCL设计师添加了这些过载?

有帮助吗?

解决方案

正如汉斯(Hans)提到的那样,一个原因是,在大多数常见的格式化字符串的情况下,创建数组是很多不必要的开销。这节省了EXE的空间。

另一个原因是,并非所有语言都支持variadic函数(使用 params 在C#中)。这允许这些语言的用户避免为字符串格式的最常见案例创建数组。这为没有简单语法的语言节省了很多用于数组创建和初始化的语言。

其他提示

您忘记了拨打电话所需的应用程序中的代码。创建数组并填充它比仅通过3个args所需的IL要多得多。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top