且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

可选参数:使用带有3个参数的方法,使用带有2个参数的相同方法

更新时间:2022-02-18 05:07:51

可选参数必须是签名中的最后一个参数。换句话说:第一个可选参数之后的所有参数也必须是可选的。因此,在您给出的示例中,您必须将参数1和4移动到方法签名的末尾,以便能够仅使用arg2,arg3,arg5调用它:

Optional parameters have to be the last parameters in the signature. Put differently: All parameters after the first optional parameter have to be optional as well. So in your given example you would have to move the parameters 1 and 4 to the end of the signature of the method in order to be able to call it with arg2, arg3, arg5 only:
void Method(int arg2, int arg3, int arg5, int arg1=0, int arg4=0)

(其中默认值0当然可以是不同的。)



有些相关,虽然不是解决方案,但是命名参数语法。如果您将所有参数声明为可选,则可以调用如下方法:

(Where the default values of 0 can be different of course.)

Somewhat related, though not a solution here, is the named argument syntax. If you declared all of your parameters as optional, you could call the method like this:

Method(arg2: 1, arg3: 2, arg5: 3);





如需进一步阅读,请查看此处:名称和可选参数 [ ^ ]



编辑:命名参数的附录:您可以将它们用于有或没有的方法调用可选参数。就像可选参数一样,第一个命名参数后面的参数也必须被命名。

大多数情况下,命名参数用于跳过可选参数:没有命名参数,如果你想提供例如,方法的第二个可选参数的值,您也必须为第一个指定值。命名参数允许您仅为您想要的那些可选参数提供值。



For further reading, take a look here: Named and Optional Arguments[^]

Addendum to named arguments: You could use them for method calls that have or have none optional parameters. Just like with optional parameters, those arguments following the first named argument also have to be named.
Most often named arguments are used to be able to skip optional parameters: Without named arguments, if you wanted to provide a value for, say, the second optional parameter of a method, you would have to specify a value for the first one, too. Named arguments allow you to provide values only for those optional parameters that you want to.


除了解决方案1.



有两种选择。可选参数功能稍后已添加到C#中,并且在它发生之前,存在较旧的机会,与允许在同一名称下具有多个方法的事实相关。通常它被称为方法重载这个令人困惑的术语。 (是的,许多初学者都非常困惑,并在这个论坛上提问。)所以,或者,你可以这样写:

In addition to Solution 1.

There are two alternatives. The optional parameters feature has been added to C# later, and before it happened, there was the older opportunity, related to the fact that it's allowed to have more than one method under the same name. Usually it's called by quite a confusing term "method overloading". (Yes, many beginners have been badly confused and asked questions on this forum.) So, alternatively, you could write:
void Method(int first, int second) { /* ... */ }
void Method(int first) {
   Method(first, 0); // 0 is the same very default value for "second" here
   // use also the parameter "first" now
   // ...
}

我想说基于可选参数的新方法更好,更明确,但有些人更喜欢上面描述的旧款式。有些人这样做是因为他们使用VS 2008(最新目标为.NET v.3.5)或更早版本。



请注意,总是存在以下情况:调用是模糊的,然后使用精确类型帮助,比如使用显式类型变量/成员/常量而不是立即常量,例如0.



对于较新的方法,重要的是要理解具有默认值的参数不仅可以是可选而且还可以是命名的,这是事件更好的特性。命名机制与位置相对;呼叫中的参数顺序可能会有所不同。请参阅:命名和可选参数(C#编程指南) [ ^ ]。



-SA

I would say that the newer approach based on optional parameters is better, more explicit, but some prefer the older style described above. Some do it because they use VS 2008 (with the latest target of .NET v.3.5) or earlier.

Note that always there are cases where the code at the call is ambiguous, then using exact types helps, say, using explicitly typed variable/members/constants instead of immediate constants, such as 0.

As to the newer approach, it's important to understand that the arguments with default values can be not only optional but also named, which is event better feature. The named mechanism is opposed to the positional one; the order of arguments at call may vary. Please see: Named and Optional Arguments (C# Programming Guide)[^].

—SA


怎么办?



当试图决定是否使用可选参数,或定义具有相同名称但不同参数列表(方法重载)的多个方法:如果无关紧要,则在一个方法定义中考虑可选参数如果该可选参数具有定义的值。换句话说,执行的代码是相同的。但是,如果您有使用不同类型参数的方法,请使用方法重载。请参阅:[ ^ ]。 b $ b

要做什么?



可选参数的潜在问题是用作参数的某些类型将自动初始化为非空值,并且您可能无法区分调用者是否通过了有效值。



例如:



private void MyMethod(int int1,string string1 =,int int2 = 0 )



在这个方法的主体中,你怎么知道'string1和'int1的值是否已经显式由调用者设置,而不是默认设置?这可能导致奇怪的代码解决方法如下:
What to do ?

When trying to decide whether to use optional parameters, or define multiple methods with the same name, but different parameter lists (method overloading): consider optional parameters in one method definition when it doesn't matter if that optional parameter has a value defined ... in other words, the code that executes is the same. However, if you have methods that use different Types of parameters, use method overloading. See: [^].

What not to do ?

A potential problem with optional parameters is that certain Types used as parameters will be auto-initialized to non-null values, and you may have trouble distinguishing whether the caller passed you a valid value, or not.

For example:

private void MyMethod(int int1, string string1 = "", int int2 = 0)

In the body of this method, how will you know if the values of 'string1, and 'int1 have been explicitly set by the caller, rather than having been set by default ? That can lead to quirky code work-arounds like this:
private void MyMethod(int int1, string string1 = null, int? int2 = null)
{
    Console.WriteLine("{0}, {1}, {2}", int1, string1, int2);

    if(string1 != null) // do something with 'string1

    if(int2 != null) // do something with 'int2
}

在哪里可以利用Type'String可以为'null,并使用nullable-Int参数允许整数条目为null 。我认为这是代码味道。



另一种策略,如果所有参数都是相同的Type ,则使用' params关键字允许可变长度参数数组:

Where you take advantage of the fact that Type 'String can be 'null, and you use a nullable-Int parameter to allow the integer entry to be null. I consider this a "code-smell."

Another strategy, if all your parameters are the same Type, is to use the 'params keyword to allow a variable length Array of parameters:

private void MyMethodWithVariableParams(params int[] intParams)
{
    foreach(int theInt in intParams)
    {
        // do something with 'theInt
    }
}

当你真的希望迭代参数数组时,这是最有用的。当你必须编写if / else语句或switch语句来处理参数Array的不同长度时,它就不那么有用了。



在我看来,我认为***尽量减少可选参数的使用,但是,如果这样做,您可以利用使用命名参数的调用语法如何跳过您不想在其中设置的参数给出方法调用。



我觉得不幸很多人称之为命名参数,好像它们是另一个类型的参数实际上,这只是一个可选的语法,用于调用方法



一个有趣的关于使用可选参数的可能缺点的论文:[ ^ ]。



当有不同的参数配置时,我更喜欢看到方法重载将被频繁调用的离子...只要:所有方法重载共同的代码被分解为一个单独的方法。



如果你使用的是.NET 4.0或更高版本,你真的想让你的代码闻起来很好,你可以使用System.Runtime.InteropServices使用'OptionalParameter属性:

This is most useful when you really want to iterate over the parameter Array. It is less useful, when you have to write if/else statements, or a switch statement, to handle different lengths of the parameter Array.

In my opinion, I think it best to minimize use of optional parameters, but, if you do, you can take advantage of how the calling syntax that uses Named Parameters allows you to skip parameters you don't want to set in a given method call.

I find it "unfortunate" that many people refer to "Named Parameters" as if they were another type of parameter that can be used in declaring a Method, when, in fact, this is only an optional syntax for calling a Method.

An interesting essay on possible drawbacks of using optional arguments: [^].

I prefer to see method-overloading when there are distinct parameter-configurations that will be called frequently ... as long as: code common to all method-overloads is factored out into a separate method.

If you are using .NET 4.0 or later, and you really want to make your code smell good, you can use the 'OptionalParameter Attribute:

using System.Runtime.InteropServices;

private void MyMethod(int int1, [OptionalParameter] string1, [OptionalParameter] int2)
{
    // whatever
}

到使用此属性,您必须引用System.Runtime.InteropServices库:但是,变量将以与没有Attribute定义的可选变量相同的方式初始化。使用此属性没有运行时性能损失。

To use this attribute, you must reference the System.Runtime.InteropServices library: however, the variables will be initialized in the same way that optional variables defined without the Attribute are. Using this Attribute has no run-time performance penalty.