views:

472

answers:

10

which one is better? at a glance optional parameter seems better (less code, less XML documentation, etc), but why do most MSDN library classes use overloading instead of optional parameters?

Is there any special thing you have to take note when you choose to use optional parameter (or overloading)?

+3  A: 

Optional parameters has to be last. So you can not add an extra parameter to that method unless its also optional. Ex:

void MyMethod(int value, int otherValue = 0);

If you want to add a new parameter to this method without overloading it has to be optional. Like this

void MyMethod(int value, int otherValue = 0, int newParam = 0);

If it can't be optional, then you have to use overloading and remove the optional value for 'otherValue'. Like this:

void MyMethod(int value, int otherValue = 0);
void MyMethod(int value, int otherValue, int newParam);

I assume that you want to keep the ordering of the parameters the same.

So using optional parameters reduces the number of methods you need to have in your class, but is limited in that they need to be last.

Update 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

So optional parameters gives the caller more possibilities.

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
}

Then when calling 'MyMethod' like this:

MyMethod(100); 

Will result in 2 method calls. But if you use optional parameters there is only one implementation of 'MyMethod' and hence, only one method call.

Martin Ingvar Kofoed Jensen
is this an important consideration?
Louis Rhys
Less code is always better. Less risk of errors and more readable.
Martin Ingvar Kofoed Jensen
you can use named parameter in conjunction with optional parameter to avoid having to define the optional parameter around the end of the code. See my post below.
Bikal Gurung
Yes, I agree. I have also added that to my post
Martin Ingvar Kofoed Jensen
+10  A: 

One good use case for 'Optional parameters' in conjunction with 'Named Parameters' in C# 4.0 is that it presents us with an elegant alternative to method overloading where you overload method based on the number of parameters.

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");
}

.....

With optional parameters in C# 4.0 you would implement the use case like the following,

public void DoFoo(int a = 10, long b = 23, string c = "Hello")

Then you could use the method like so - Note the use of named parameter -

DoFoo(c:"Hello There, John Doe")

This call takes parameter a value as 10 and parameter b as 23. Another variant of this call - notice you don't need to set the parameter values in the order as they appear in the method signature, the named parameter makes the value explicit.

DoFoo(c:"hello again", a:100) 

Another benefit of using named parameter is that it greatly enhances readability and thus code maintenance of optional parameter methods.

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.

Bikal Gurung
+1  A: 

One benefit of using optional parameters is that you need not have to do a conditional check in your methods like if a string was null or empty if one of the input parameter was a string. As there would be a default value assigned to the optional parameter, the defensive coding will be reduced to a great extent.

Named parameters give the flexibility of passing parameter values in any order.

Nilesh Gule
A: 

Neither is difinitively "better" than the other. They both have their place in writing good code. Optional parameters should be used if the parameters can have a default value. Method overloading should be used when the difference in signature goes beyond not defining parameters that could have default values (such as that the behavior differs depending on which parameters are passed, and which are left to the default).

// 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)
{
    ...
}
Michael Meadows
+3  A: 

This one almost goes without saying, but:

Not all languages support optional parameters. If you want your libraries to be friendly to those languages, you have to use overloads.

Granted, this isn't even an issue for most shops. But you can bet it's why Microsoft doesn't use optional parameters in the Base Class Library.

Joe White
what happens if you use a library with an optional parameter from a language that does not support it (ex. C# 2.0)?
Louis Rhys
C# 2.0 ignores the "optional parameter" flag, and treats all parameters as required. So every call site has to provide a value for every parameter.
Joe White
+4  A: 

Optional Parameters provide issues when you expose them publicly as API. A rename of a parameter can lead to issues. Changing the default value leads to issues (See e.g. here for some info: Caveats of C# 4.0 optional parameters)

Also, optional params can only be used for compile-time constants. Compare this:

public static void Foo(IEnumerable<string> items = new List<string>()) {}
// Default parameter value for 'items' must be a compile-time constant

to this

public static void Foo() { Foo(new List<string>());}
public static void Foo(IEnumerable<string> items) {}
//all good
flq
A: 

To address your first question,

why do most MSDN library classes use overloading instead of optional parameters?

It is for backward compatibility.

When you open a C# 2, 3.0 or 3.5 project in VS2010, it is automatically upgraded.

Just imagine the inconvenience it would create if each of the overloads used in the project had to be converted to match the corresponding optional parameter declaration.

Besides, as the saying goes, "why fix what is not broken?". It is not necessary to replace overloads that already work with new implementations.

Alex Essilfie
+1  A: 

I believe they serve different purposes. Optional parameters are for when you can use a default value for a parameter, and the underlying code will be the same:

public CreditScore CheckCredit( 
  bool useHistoricalData = false,  
  bool useStrongHeuristics = true) { 
  // ... 
}

Method overloads are for when you have mutually-exclusive (subsets) of parameters. That normally means that you need to preprocess some parameters, or that you have different code altogether for the different "versions" of your method (note that even in this case, some parameters can be shared, that's why I mentioned "subsets" above):

public void SendSurvey(IList<Customer> customers, int surveyKey) {  
  // will loop and call the other one 
} 
public void SendSurvey(Customer customer, int surveyKey) {  
  ...  
}

(I wrote about this some time ago: http://codecrafter.blogspot.com/2009/08/optional-parameters-and-method.html)

Jordão
A: 

What about a 3rd option: pass an instance of a class with properties corresponding to various "optional parameters".

This provides the same benefit as named and optional parameters, but I feel that this is often much clearer. It gives you an opportunity to logically group parameters if necessary (i.e. with composition) and encapsulate some basic validation as well.

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.

Michael Petito
+1  A: 

A good place to use optional parameter is WCF since it does not support method overloading.

ashraf