我知道这是一个很基本的问题,但我找不到答案。

为什么要用它?如果你编写的函数或方法正在使用它,当你删除它时,代码仍然可以完美地工作,100%没有它。例句:

参数:

static public int addTwoEach(params int[] args)
{
    int sum = 0;
    foreach (var item in args)
        sum += item + 2;
    return sum;
}

无参数:

static public int addTwoEach(int[] args)
{
    int sum = 0;
    foreach (var item in args)
       sum += item + 2;
    return sum;
}

当前回答

另一个例子

public IEnumerable<string> Tokenize(params string[] words)
{
  ...
}

var items = Tokenize(product.Name, product.FullName, product.Xyz)

其他回答

使用params关键字的一个危险是,如果对方法的调用已经编码,

有人不小心/故意地从方法签名中删除一个/多个必需的参数, 而且 在签名更改之前,一个/多个必需的参数与params参数类型兼容。

这些调用将继续编译一个/多个表达式,这些表达式之前用于必要的参数被视为可选的参数参数。我只是遇到了最糟糕的情况:params参数的类型是对象[]。

这一点是值得注意的,因为开发人员已经习惯了编译器在更常见的情况下把参数从一个方法中删除(因为期望的参数#会改变)。

对我来说,不值得抄近路。(类型)[]没有参数将工作在0到无穷大#参数,而不需要覆盖。最坏的情况是,你将不得不添加一个,new (Type)[]{}到不适用的调用。

顺便说一句,恕我直言,最安全(也是最易读的做法)的做法是:

pass via Named Parameters (which we can now do even in C# ~2 decades after we could in VB ;P), because: 1.1. it's the only way that guarantees prevention of unintended values passed to Parameters after Parameter order, Compatible-Type and/or count change after Calls have been coded, 1.2. it reduces those chances after a Parameter meaning change, because the likely new identifier name reflecting the new meaning is right next to the value being passed to it, 1.3. it avoids having to count commas and jump back & forth from Call to Signature to see what Expression is being passed for what Parameter, and 1.3.1. By the way, this reason alone should be plenty (in terms of avoiding frequent error-prone violations of the DRY Principle just to read the code not to mention also modify it), but this reason can be exponentially more important if there are one/more Expressions being Passed that themselves contain commas, i.e. Multi-Dimensional Array Refs or Multi-Parameter Function Calls. In that case, you couldn't even use (which even if you could, would still be adding an extra step per Parameter per Method Call) a Find All Occurrences in a Selection feature in your editor to automate the comma-counting for you. 1.4. if you must use Optional Parameters (params or not), it allows you to search for Calls where a particular Optional Parameter is Passed (and therefore, most likely is not or at least has the possibility of being not the Default Value),

(注:原因1.2.;和1.3。可以减轻和减少错误的机会,甚至在编码初始调用时,更不用说当调用必须读取和/或更改时。))

and

do so ONE - PARAMETER - PER - LINE for better readability (because: 2.1. it's less cluttered, and 2.2. it avoids having to scroll right & back left (and having to do so PER - LINE, since most mortals can't read the left part of multiple lines, scroll right and read the right part)). 2.3. it's consistent with the "Best Practice" we've already evolved into for Assignment Statements, because every Parameter Passed is in essence an Assignment Statement (assigning a Value or Reference to a Local Variable). Just like those who follow the latest "Best Practice" in Coding Style wouldn't dream of coding multiple Assignment Statements per line, we probably shouldn't (and won't once "Best Practice" catches up to my "genius" ;P ) do so when Passing Parameters.

注:

Passing in Variables whose names mirror the Parameters' doesn't help when: 1.1. you're passing in Literal Constants (i.e. a simple 0/1, false/true or null that even "'Best Practices'" may not require you use a Named Constant for and their purpose can't be easily inferred from the Method name), 1.2. the Method is significantly lower-level / more generic than the Caller such that you would not want / be able to name your Variables the same/similar to the Parameters (or vice versa), or 1.3. you're re-ordering / replacing Parameters in the Signature that may result in prior Calls still Compiling because the Types happen to still be compatible. Having an auto-wrap feature like VS does only eliminates ONE (#2.2) of the 8 reasons I gave above. Prior to as late as VS 2015, it did NOT auto-indent (!?! Really, MS?!?) which increases severity of reason #2.2.

VS should have an option that generates Method Call snippets with Named Parameters (one per line of course ;P) and a compiler option that requires Named Parameters (similar in concept to Option Explicit in VB which, btw, the requirement of was prolly once thought equally as outrageous but now is prolly required by "'Best Practices'"). In fact, "back in my day" ;), in 1991 just months into my career, even before I was using (or had even seen) a language with Named Parameters, I had the anti-sheeple / "just cuz you can, don't mean you should" / don't blindly "cut the ends of the roast" sense enough to simulate it (using in-line comments) without having seen anyone do so. Not having to use Named Parameters (as well other syntax that save "'precious'" source code keystrokes) is a relic of the Punch Card era when most of these syntaxes started. There's no excuse for that with modern hardware and IDE's and much more complex software where readability is much, Much, MUCH more important. "Code is read much more often than is written". As long as you're not duplicating non-auto-updated code, every keystroke saved is likely to cost exponentially more when someone (even yourself) is trying to read it later.

Params还允许使用单个参数调用方法。

private static int Foo(params int[] args) {
    int retVal = 0;
    Array.ForEach(args, (i) => retVal += i);
    return retVal;
}

例如Foo (1);而不是Foo(new int[] {1});在需要传递单个值而不是整个数组的场景中,可以用于简化。它仍然在方法中以相同的方式处理,但为这种方式调用提供了一些糖果。

还有一件重要的事情需要强调。最好使用参数,因为它的性能更好。当你调用一个带有params参数的方法时,什么都没有传递给它:

public void ExampleMethod(params string[] args)
{
// do some stuff
}

电话:

ExampleMethod();

然后。net Framework的新版本(从。net Framework 4.6开始):

ExampleMethod(Array.Empty<string>());

这个数组。空对象以后可以被框架重用,所以不需要做多余的分配。这些分配将在你像这样调用这个方法时发生:

 ExampleMethod(new string[] {});

使用参数可以不带参数地调用函数。无参数:

static public int addTwoEach(int[] args)
{
    int sum = 0;

    foreach (var item in args)
    {
        sum += item + 2;
    }

    return sum;
}

addtwoEach(); // throws an error

与参数比较:

static public int addTwoEach(params int[] args)
{
    int sum = 0;

    foreach (var item in args)
    {
        sum += item + 2;
    }

    return sum;
}

addtwoEach(); // returns 0

通常,当参数的数量从0到无穷大时,可以使用参数;当参数的数量从1到无穷大时,可以使用数组。

不需要创建重载方法,只需使用一个带有参数的方法,如下所示

// Call params method with one to four integer constant parameters.
//
int sum0 = addTwoEach();
int sum1 = addTwoEach(1);
int sum2 = addTwoEach(1, 2);
int sum3 = addTwoEach(3, 3, 3);
int sum4 = addTwoEach(2, 2, 2, 2);