我正在使用Reflector来查看String.Format的实现,并且一直认为String.Format的重载占用了1,2和1。 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设计师会增加这些重载?
答案 0 :(得分:7)
汉斯提到,其中一个原因是,在格式化字符串的大多数常见情况下,创建数组会带来很多不必要的开销。这节省了EXE中的空间。
另一个原因是并非所有语言都支持可变参数函数(在C#中使用params
)。这允许这些语言的用户避免为最常见的字符串格式化情况创建数组。对于没有简单的数组创建和初始化语法的语言,这可以节省很多。
答案 1 :(得分:3)
您忘记了拨打电话所需的应用中的代码。创建数组并填充它需要比传递3个参数更多的IL。