具有无限参数的 c# 方法或具有数组或列表的方法?

Ric*_*tos 23 c# methods

我最近了解到您可以创建一些具有无限参数的方法,例如:

SomeMethod(params int[] numbers);
Run Code Online (Sandbox Code Playgroud)

但我的问题是,这与仅创建一个接收列表或数组的方法有什么区别?

SomeMethod(int[] numbers);
SomeMethod(List<int> numbers);
Run Code Online (Sandbox Code Playgroud)

也许它对性能有一些影响?我不完全理解或看到您更喜欢具有无限参数的方式。

在谷歌上快速搜索没有帮助,我希望你能帮助我。

Eri*_*ert 33

这与仅创建一个接收列表或数组的方法有什么区别?

和...之间的不同

void M(params int[] x)
Run Code Online (Sandbox Code Playgroud)

和

void N(int[] x)
Run Code Online (Sandbox Code Playgroud)

是 M 可以这样调用:

M(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

或者像这样:

M(new int[] { 1, 2, 3 });
Run Code Online (Sandbox Code Playgroud)

但 N 只能以第二种方式调用,而不是第一种方式。

也许它对性能有一些影响?

对性能的影响是,无论您M以第一种方式还是第二种方式调用,无论哪种方式都会创建一个数组。创建阵列会影响性能,因为它既需要时间也需要内存。请记住,应根据绩效目标来衡量绩效影响;创建额外阵列的成本不太可能是决定市场成功与失败的门控因素。

我不完全理解或看到您更喜欢具有无限参数的方式。

对于调用该方法的代码的作者来说,这纯粹是一种方便;它更短更容易写

M(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)

而不是写作

M(new int[] { 1, 2, 3 });
Run Code Online (Sandbox Code Playgroud)

它只是在呼叫者一侧节省了几次按键操作。就这些。

一些您没有问过但可能想知道答案的问题:

这个功能叫什么?

允许在调用方传递可变数量参数的方法称为variadic。参数方法是 C# 实现可变参数方法的方式。

重载解析如何与可变参数方法一起工作?

当面临重载解析问题时,C# 会同时考虑“普通”和“扩展”形式,如果两者都适用,“普通”形式总是获胜。例如,考虑这个:

void P(params object[] x){}
Run Code Online (Sandbox Code Playgroud)

我们有一个电话

P(null);
Run Code Online (Sandbox Code Playgroud)

有两种适用的可能性。在“正常”形式中,我们调用P并传递数组的空引用。在“扩展”形式中,我们调用P(new object[] { null }). 在这种情况下,正常形式获胜。如果我们有一个电话,P(null, null)那么普通表格不适用,默认情况下扩展表格获胜。

挑战:假设我们有var s = new[] { "hello" };一个电话P(s);。描述呼叫站点发生的情况以及原因。你可能会感到惊讶!

挑战:假设我们同时拥有void P(object x){}和void P(params object[] x){}。有什么作用P(null),为什么?

挑战:假设我们同时拥有void M(string x){}和void M(params string[] x){}。有什么作用M(null),为什么?这与之前的案例有何不同?


dig*_*rld 5

刚做了一个小原型。答案似乎params只是传递数组的语法糖。这真的不是什么意外。我创建了相同方法的两个版本,唯一的区别是“params”关键字。为两者生成的 IL 是相同的,除了 aSystem.ParamArrayAttribute应用于params版本。

此外,在调用站点生成的 IL 在我使用手动声明new int[]调用方法和仅使用params参数调用方法之间也是相同的。

所以,答案似乎是“方便”。性能上似乎没有任何差异。您也可以params使用数组调用函数,因此这也不足为奇。这归结为对于您的方法的使用者来说,使用任意数量的参数(例如someMethod(1, 2, 3))调用它是否比总是首先创建一个集合(例如someMethod(new List<int>() { 1, 2, 3 } ))更容易。