Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

method overloading vs optional parameter in C# 4.0 [duplicate]

People also ask

Are optional parameters bad practice?

The thing with optional parameters is, they are BAD because they are unintuitive - meaning they do NOT behave the way you would expect it. Here's why: They break ABI compatibility ! so you can change the default-arguments at one place.

What are the differences between mandatory parameters and optional parameters?

The main difference between required parameters and optional parameters is that mandatory parameters must be provided when the function is called, while optional parameters automatically supplies the value if it's not provided.

Can method overloading have different parameters?

No, you cannot overload a method based on different return type but same argument type and number in java. same name. different parameters (different type or, different number or both).

What is a optional parameter?

A method that contains optional parameters does not force to pass arguments at calling time. It means we call method without passing the arguments. The optional parameter contains a default value in function definition. If we do not pass optional argument value at calling time, the default value is used.


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.


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

Update

Here's some additional reading material when a constructor with default parameters does not play nicely with Reflection.


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 here)


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.


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.