简体   繁体   English

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

[英]c# method with unlimited params or method with an array or list?

I recently learned that you can create some method with unlimited parameters, for example:我最近了解到您可以创建一些具有无限参数的方法,例如:

SomeMethod(params int[] numbers);

but my question is, what's the difference between that and just creating a method that receives a list or an array?但我的问题是,这与仅创建一个接收列表或数组的方法有什么区别?

SomeMethod(int[] numbers);
SomeMethod(List<int> numbers);

perhaps it has some impact in performance?也许它对性能有一些影响? I don't fully understand or see in what way you would prefer the one with unlimited parameters.我不完全理解或看到您更喜欢具有无限参数的方式。

A quick search on google didn't help, I hope you could help me.在谷歌上快速搜索没有帮助,我希望你能帮助我。

what's the difference between that and just creating a method that receives a list or an array?这与仅创建一个接收列表或数组的方法有什么区别?

The difference between和...之间的不同

void M(params int[] x)

and

void N(int[] x)

is that M may be called like this:是 M 可以这样调用:

M(1, 2, 3)

or like this:或者像这样:

M(new int[] { 1, 2, 3 });

but N may only be called in the second way, not the first way.但 N 只能以第二种方式调用,而不是一种方式。

perhaps it has some impact in performance?也许它对性能有一些影响?

The impact to performance is that whether you call M in the first way or the second way, either way you get an array created.对性能的影响在于,无论您以第一种方式还是第二种方式调用M ,您都会创建一个数组。 Creating an array has a performance impact because it takes both time and memory.创建阵列会影响性能,因为它既需要时间也需要内存。 Remember that performance impacts should be measured against performance goals;请记住,应根据绩效目标来衡量绩效影响; it is unlikely that the cost of creating an extra array is the gating factor that is the difference between success and failure in the marketplace.创建额外阵列的成本不太可能是决定市场成功与失败的门控因素。

I don't fully understand or see in what way you would prefer the one with unlimited parameters.我不完全理解或看到您更喜欢具有无限参数的方式。

It is purely and entirely a convenience for the author of the code which is calling the method;对于调用该方法的代码的作者来说,这纯粹是一种方便; it is simply shorter and easier to write更短更容易

M(1, 2, 3);

instead of writing而不是写作

M(new int[] { 1, 2, 3 });

It just saves a few keystrokes on the caller's side.它只是在呼叫者一侧节省了几次按键操作。 That is all.就这些。

A few questions you did not ask but perhaps would like to know the answer to:一些您没有问过但可能想知道答案的问题:

What is this feature called?这个功能叫什么?

Methods that allow a variable number of arguments to be passed on the caller side are called variadic .允许在调用方传递可变数量参数的方法称为variadic Params methods are how C# implements variadic methods.参数方法是 C# 实现可变参数方法的方式。

How does overload resolution work with a variadic method?重载解析如何与可变参数方法一起工作?

When faced with an overload resolution problem, C# will consider both the "normal" and "expanded" forms, and the "normal" form always wins if both are applicable.当面临重载解析问题时,C# 会同时考虑“普通”和“扩展”形式,如果两者都适用,“普通”形式总是获胜。 For example, consider this:例如,考虑这个:

void P(params object[] x){}

and we have a call我们有一个电话

P(null);

There are two applicable possibilities.有两种适用的可能性。 In "normal" form, we call P and pass a null reference for the array.在“正常”形式中,我们调用P并为数组传递一个空引用。 In "expanded" form, we call P(new object[] { null }) .在“扩展”形式中,我们调用P(new object[] { null }) In this case, normal form wins.在这种情况下,正常形式获胜。 If we had a call P(null, null) then normal form is inapplicable and expanded form wins by default.如果我们有一个调用P(null, null)那么普通形式不适用,默认情况下扩展形式获胜。

Challenge : Suppose we have var s = new[] { "hello" };挑战:假设我们有var s = new[] { "hello" }; and a call P(s);和一个呼叫P(s); . . Describe what happens at the call site and why.描述呼叫站点发生的情况以及原因。 You might be surprised!你可能会感到惊讶!

Challenge : Suppose we have both void P(object x){} and void P(params object[] x){} .挑战:假设我们有void P(object x){}void P(params object[] x){} What does P(null) do, and why? P(null)做什么,为什么?

Challenge : Suppose we have both void M(string x){} and void M(params string[] x){} .挑战:假设我们有void M(string x){}void M(params string[] x){} What does M(null) do, and why? M(null)做什么,为什么? How does this differ from the previous case?这与之前的案例有何不同?

Just did a little prototype.刚做了一个小原型。 The answer appears to be that params is simply syntactic sugar for passing in an array.答案似乎是params只是传递数组的语法糖。 That's not really a surprise.这真的不是什么意外。 I created two versions of the same method, where the only difference is the "params" keyword.我创建了相同方法的两个版本,唯一的区别是“params”关键字。 The IL generated for both was identical, except that a System.ParamArrayAttribute was applied to the params version.为两者生成的 IL 是相同的,只是System.ParamArrayAttribute应用于params版本。

Further, the IL generated at the call site was also the same between me calling the method with a manually declared new int[] and calling the method just using the params arguments.此外,在调用站点生成的 IL 在我使用手动声明的new int[]调用方法和仅使用params参数调用方法之间也是相同的。

So, the answer seems to be "convenience".所以,答案似乎是“方便”。 There doesn't appear to be any difference in performance.性能上似乎没有任何差异。 You can also call a params function with an array instead, so that's also not terribly surprising.您也可以使用数组调用params函数,因此这也不足为奇。 It comes down to if it's easier for the consumer of your method to call it with any number of parameters (eg someMethod(1, 2, 3) ) than to always have to create a collection first (eg someMethod(new List<int>() { 1, 2, 3 } ) ).这归结为对于您的方法的使用者来说,使用任意数量的参数(例如someMethod(1, 2, 3) )调用它是否比总是首先创建一个集合更容易(例如someMethod(new List<int>() { 1, 2, 3 } ) )。

The feature of unlimited parameters offers the following benefits in many scenarios:无限参数的特性在许多场景中提供了以下好处:

  1. Loose coupling松耦合
  2. Enhanced reusability增强的可重用性
  3. Better overall performance of the application更好的应用程序整体性能

Here is an example where the unlimited parameters option is a great choice这是一个示例,其中无限制参数选项是一个不错的选择

Consider that an application for sending emails needs to be built.考虑需要构建用于发送电子邮件的应用程序。

The function that sends the email must be able to handle either single or multiple values for the 'To', 'CC' and 'BCC' fields.发送电子邮件的函数必须能够处理“收件人”、“抄送”和“密件抄送”字段的单个或多个值。

If the types of parameters are fixed to be arrays or lists for all fields (To, CC, BCC), then the calling function will be forced to deal with all the complexity of defining 3 arrays or lists in order to call the email sender function.如果所有字段(To、CC、BCC)的参数类型固定为数组或列表,那么调用函数将被迫处理定义3个数组或列表的所有复杂性,以便调用电子邮件发送函数.

Even if the caller wants to send an email to just one address, the email sender function will force the caller to define and send 3 different arrays as parameters.即使调用者只想向一个地址发送一封电子邮件,电子邮件发送器函数也会强制调用者定义并发送 3 个不同的数组作为参数。

If the email sender function takes the unlimited params approach, then the caller function need not deal with all the complexity.如果电子邮件发送方函数采用无限制参数方法,则调用方函数无需处理所有复杂性。

The unlimited parameters approach contributes to better runtime perfomance of the application by avoiding the creation of arrays or lists wherever unnecessary.通过避免在不必要的地方创建数组或列表,无限参数方法有助于提高应用程序的运行时性能。

From a non-performance , style perspective, the params keyword is really nice to have when you want to send optional list of parameters.非性能、风格的角度来看,当您想要发送可选的参数列表时, params关键字非常有用。

Personally, I would use params when my code was something like就个人而言,我会用params当我的代码是像

SomeMethod('Option1', 'Option17');

void SomeMethod(params string[] options)
{
    foreach(var option in options)
    {
        switch(option): ...
    }
}

The nice part about this is that I can use this method all over the place without having to create an array or list every time.关于这个的好处是我可以在任何地方使用这个方法,而不必每次都创建一个数组或列表。

I would use array or list when I know I will always be passing this function a set of data that is already put together like当我知道我将始终向这个函数传递一组已经放在一起的数据时,我会使用arraylist

List<User> users = GetUsersFromDB();
SomeMethod(users);

I see the benefit of params in the flexibility that it adds.我看到params的好处在于它增加的灵活性。 It may be a relatively minor impact to your code, but it is still a nice tool to have.它可能对您的代码的影响相对较小,但它仍然是一个不错的工具。

The calling convention is different.调用约定不同。 For example ...例如 ...

public class Test
{
    public void Method1( params int[] nums )
    {
        nums.ToList().ForEach( n => Console.WriteLine(n) );
    }

    public void Method2( List<int> nums )
    {
        nums.ForEach( n  => Console.WriteLine(n) );
    }   
}

void Main()
{   
    var t = new Test();
    t.Method1( 1, 2, 3, 4 );
    t.Method2( new List<int>() { 1, 2, 3, 4 } );
}

In the first case, you can pass as many ints as separate parameters to the method.在第一种情况下,您可以将尽可能多的整数作为单独的参数传递给方法。 In the second, you would need to instantiate a list and pass it.在第二种情况下,您需要实例化一个列表并传递它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM