【发布时间】:2015-10-08 09:50:48
【问题描述】:
如果您现在在 IDE 中输入string.Format,您会看到有 4 种不同的重载:一个采用字符串和对象,另一个采用字符串和两个对象,然后一个采用三个对象,以及最后一个使用params。根据this answer 的说法,这是因为params 生成了'overhead',其他一些语言可能不支持。
我的问题是,为什么不能像这样调用方法:
void Foo()
{
Bar(1, 2, 3);
}
void Bar(params int[] args)
{
// use args...
}
在编译时本质上被转换为
void Foo()
{
Bar(new[] { 1, 2, 3 });
}
void Bar(int[] args)
{
// use args...
}
?然后它不会产生任何开销,除了创建数组(无论如何都是必要的),并且与其他语言完全兼容。
参数的数量在编译时就已经知道了,那么是什么阻止了 C# 编译器进行某种字符串替换并使第一个场景本质上是第二个场景的语法糖呢?为什么我们必须专门实现hidden language features 来支持可变参数?
【问题讨论】:
-
数组创建是有关的开销链接答案。你没有摆脱这种开销。为重载提供一个、两个、三个参数确实使得在使用少于 4 个项目时调用数组分配是不必要的。
-
-
内存开销不是这里唯一的问题 - 创建一个数组并用项目填充它会在您的方法中生成额外的 IL,这使得它不太可能被 JIT 内联。
-
这只是一个猜测,但是如果编译器知道一个方法只需要 n 个参数而不是可变数量的参数,它可能能够更好地优化代码的性能,例如将变量存储在注册而不是创建一个数组。
-
@Matthew 和 MarcinJuraszek,如果它只是调用一个方法来执行您试图避免的操作,那么优化/内联代码有什么意义 - 创建一个数组,用 3 个元素填充它,然后传递它到
params过载?
标签: c# params variadic-functions