void MyMethod(int value, int otherValue = 0, int newParam = 0);
如果它不能是可选的,那么你必须使用重载,并删除“ other Value”的可选值。像这样:
void MyMethod(int value, int otherValue = 0);
void MyMethod(int value, int otherValue, int newParam);
我假设您希望保持参数的顺序不变。
因此,使用可选参数可以减少类中需要的方法的数量,但是它们的数量有限,因为它们必须是最后一个。
更新
When calling methods with optional parameters, you can used named parameters like this:
void MyMethod(int value, int otherValue = 0, int newValue = 0);
MyMethod(10, newValue: 10); // Here I omitted the otherValue parameter that defaults to 0
因此,可选参数为调用者提供了更多的可能性。
One last thing. If you use method overloading with one implementation, like this:
void MyMethod(int value, int otherValue)
{
// Do the work
}
void MyMethod(int value)
{
MyMethod(value, 0); // Do the defaulting by method overloading
}
C # 4.0中“可选参数”和“命名参数”的一个很好的用例是,它为我们提供了一个优雅的方法重载替代方法,即根据参数数量重载方法。
For example say you want a method foo to be be called/used like so, foo(), foo(1), foo(1,2), foo(1,2, "hello"). With method overloading you would implement the solution like this,
///Base foo method
public void DoFoo(int a, long b, string c)
{
//Do something
}
/// Foo with 2 params only
public void DoFoo(int a, long b)
{
/// ....
DoFoo(a, b, "Hello");
}
public void DoFoo(int a)
{
///....
DoFoo(a, 23, "Hello");
}
.....
使用 C # 4.0中的可选参数,您可以像下面这样实现用例,
public void DoFoo(int a = 10, long b = 23, string c = "Hello")
然后您可以像这样使用方法-注意命名参数的使用-
DoFoo(c:"Hello There, John Doe")
This call takes parameter a value as 10 and parameter b as 23.
这个调用的另一个变体——注意,不需要按照方法签名中出现的顺序设置参数值,命名参数使得值显式化。
DoFoo(c:"hello again", a:100)
使用命名参数的另一个好处是,它极大地提高了可读性,从而增强了可选参数方法的代码维护。
Note how one method pretty much makes redundant having to define 3 or more methods in method overloading. This I have found is a good use case for using optional parameter in conjunction with named parameters.
// this is a good candidate for optional parameters
public void DoSomething(int requiredThing, int nextThing = 12, int lastThing = 0)
// this is not, because it should be one or the other, but not both
public void DoSomething(Stream streamData = null, string stringData = null)
// these are good candidates for overloading
public void DoSomething(Stream data)
public void DoSomething(string data)
// these are no longer good candidates for overloading
public void DoSomething(int firstThing)
{
DoSomething(firstThing, 12);
}
public void DoSomething(int firstThing, int nextThing)
{
DoSomething(firstThing, nextThing, 0);
}
public void DoSomething(int firstThing, int nextThing, int lastThing)
{
...
}
public void SendSurvey(IList<Customer> customers, int surveyKey) {
// will loop and call the other one
}
public void SendSurvey(Customer customer, int surveyKey) {
...
}
Also, if you expect clients that consume your methods to do any kind of metaprogramming (such as building linq expressions involving your methods), I think that keeping the method signature simple has its advantages.
void DoSomething(string value = "") // Unfortunately string.Empty is not a compile-time constant and cannot be used as default value
{
if(value == null)
throw new ArgumentNullException();
}
DoSomething(); // OK, will use default value of ""
DoSomething(null); // Will throw