Should You Declare Methods Using Overloads or Optional Parameters in C# 4.0

Should you declare methods using overloads or optional parameters in C# 4.0?

I'd consider the following:

  • Do you need your code to be used from languages which don't support optional parameters? If so, consider including the overloads.
  • Do you have any members on your team who violently oppose optional parameters? (Sometimes it's easier to live with a decision you don't like than to argue the case.)
  • Are you confident that your defaults won't change between builds of your code, or if they might, will your callers be okay with that?

I haven't checked how the defaults are going to work, but I'd assume that the default values will be baked into the calling code, much the same as references to const fields. That's usually okay - changes to a default value are pretty significant anyway - but those are the things to consider.

method overloading vs optional parameter in C# 4.0

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.

Conflicting overloaded methods with optional parameters

From MSDN:

If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.

Is there a way to do C# 4.0 optional parameters in 2.0?

Your code is the standard way to do this; it isn't an ugly hack.

However, you should consider taking an int? and passing null rather than -1.

You can create optional parameters in C# 2 to be called from C# 4, using attributes.

optional parameters, overloaded methods or properties

I would suggest definitely oveloaded methods, as their TypeSafe not like parameters {objects}, and as quantity of parameters increases you should have control on length of parameters arrays Length and all that mess. Never like that approach, so I'm, definitely, for overloading.
Regards.

Performance differences between overloading or optional parameters?

I just did a quick test and the compiler optimizes the code. This basic example Main method.

public static void OptionalParamMethod(bool input, string input2 = null)
{
}

public static void Main(string[] args)
{
OptionalParamMethod(true);
OptionalParamMethod(false, "hello");
}

Compiles to this so the optional params are filled in by the compiler.

public static void Main(string[] args)
{
OptionalParamMethod(true, null);
OptionalParamMethod(false, "hello");
}

As for performance you could argue optional parameters have a slight advantage as there is only a single method call rather than chained method calls like you would normally have for an overloaded method. The code below is compiled output to show what I am talking about. The difference is quite academic though and I doubt you would ever notice in practice.

public static void Main(string[] args)
{
OptionalParamMethod(true, null);
OptionalParamMethod(false, "hello");
OverloadParamMethod(true);
OverloadParamMethod(false, "hello");
}

public static void OptionalParamMethod(bool input, [Optional, DefaultParameterValue(null)] string input2)
{
Console.WriteLine("OptionalParamMethod");
}

public static void OverloadParamMethod(bool input)
{
OverloadParamMethod(input, null);
}

public static void OverloadParamMethod(bool input, string input2)
{
Console.WriteLine("OverloadParamMethod");
}

C# 5.0 optional parameters versus method overloads

if the internal implemantaion of the function is quite differnet ,then use method overloading.Otherwise, use optional parameters.

Optional parameters methods allow you to write a single testing method instead of writing a testing method for every overloaded method

Optional Parameters, Good or Bad?

I'll start by prefacing my answer by saying Any language feature can be used well or it can be used poorly. Optional parameters have some drawbacks, just like declaring locals as var does, or generics.

What are these side effects

Two come to mind.

The first being that the default value for optional parameters are compile time constants that are embedded in the consumer of the method. Let's say I have this class in AssemblyA:

public class Foo
{
public void Bar(string baz = "cat")
{
//Omitted
}
}

And this in AssemblyB:

public void CallBar()
{
new Foo().Bar();
}

What really ends up being produced is this, in assemblyB:

public void CallBar()
{
new Foo().Bar("cat");
}

So, if you were to ever change your default value on Bar, both assemblyA and assemblyB would need to be recompiled. Because of this, I tend not to declare methods as public if they use optional parameters, rather internal or private. If I needed to declare it as public, I would use overloads.

The second issue being how they interact with interfaces and polymorphism. Take this interface:

public interface IBar
{
void Foo(string baz = "cat");
}

and this class:

public class Bar : IBar
{
public void Foo(string baz = "dog")
{
Console.WriteLine(baz);
}
}

These lines will print different things:

IBar bar1 = new Bar();
bar1.Foo(); //Prints "cat"
var bar2 = new Bar();
bar2.Foo(); //Prints "dog"

Those are two negatives that come to mind. However, there are positives, as well. Consider this method:

void Foo(string bar = "bar", string baz = "baz", string yat = "yat")
{
}

Creating methods that offer all the possible permutations as default would be several if not dozens of lines of code.

Conclusion: optional parameters are good, and they can be bad. Just like anything else.

C# 4.0, optional parameters and params do not work together

Your only option right now is to overload the TestOptional (as you had to do before C# 4). Not preferred, but it cleans up the code at the point of usage.

public static void TestOptional(string A, params string[] C)
{
TestOptional(A, 0, C);
}

public static void TestOptional(string A, int B, params string[] C)
{
Console.WriteLine(A);
Console.WriteLine(B);
Console.WriteLine(C.Count());
}

Why aren't optional parameters just compiled into equivalent overloads in C#?

One reason is that if the compiler automatically compiled down optional parameters into the overloads, it would conflict with the developers ability to define them on their own. For example the following code is legal.

class Container {

public void Example(int x) {
...
}

public void Example(int x, int y = 42) {
...
}
}


Related Topics



Leave a reply



Submit