为什么存在String.format的过载?
-
04-10-2019 - |
题
我正在使用反射器来查看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要多得多。
不隶属于 StackOverflow