This question already has an answer here:
-
method overloading vs optional parameter in C# 4.0 [duplicate]
11 answers
Since C# added optional parameters is it considered a better practice to use optional parameters or method overloads or is there a particular case where you would want to use one over the other. i.e a function w/ lots of parameters would be better suited w/ optional parameters?
Optional parameters are nice, but should be used when it makes sense. Optional parameters often muddy the intent of the method -- If there is another alternative I would lean towards the alternative.
Part of the need for optional parameters and named parameters is because COM allowed optional and name parameters:
MSDN
Some APIs, most notably COM interfaces
such as the Office automation APIs,
are written specifically with named
and optional parameters in mind. Up
until now it has been very painful to
call into these APIs from C#, with
sometimes as many as thirty arguments
having to be explicitly passed, most
of which have reasonable default
values and could be omitted.
SomeNewKid from forums.asp.net puts succinctly:
http://forums.asp.net/t/386604.aspx/1
...overloaded methods are generally
preferable to optional parameters.
Why? To keep each of your methods
clear in purpose. That is, each method
should do one thing well. As soon as
you introduce optional parameters, you
are diluting the cleanliness of that
method, and introducing branching
logic that is probably best kept out
of a method. This clarity of purpose
becomes even more important when you
start using inheritance. If you
override a method that has one or more
optional parameters, they become
harder to work with. So, I'd suggest
that for anything other than quick and
dirty classes, you use overloading in
preference to optional parameters.
Keep in mind that optional parameters are a syntactical sugar:
Reflector C#:
public class Class1
{
// Methods
public Class1()
{
this.Method1("3", "23");
}
public void Method1(string one, [Optional, DefaultParameterValue("23")] string two)
{
}
}
IL:
.class public auto ansi beforefieldinit Class1
extends [mscorlib]System.Object
{
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: call instance void [mscorlib]System.Object::.ctor()
L_0006: nop
L_0007: nop
L_0008: ldarg.0
L_0009: ldstr "3"
L_000e: ldstr "23"
L_0013: call instance void WebApplication1.Class1::Method1(string, string)
L_0018: nop
L_0019: nop
L_001a: ret
}
.method public hidebysig instance void Method1(string one, [opt] string two) cil managed
{
.param [2] = string('23')
.maxstack 8
L_0000: nop
L_0001: ret
}
}
Code Analysis in Visual Studio and FxCop recommends you do not use optional arguments in public APIs (rule CA1026: Default parameters should not be used). The reason given is that not all .NET languages support them.
I think a better reason to avoid them though, is that they can introduce either runtime or compile-time problems if you add more overloads in a version 2.0 of your API. Phil Haack explains here.
I'm going to adopt Phil's conclusion: Optional parameters were designed to support COM interop; if you're not using COM, leave them alone.
I'm not sure there's a canonical answer for this - it's subjective and case-by-case. However, in my opinion optional parameters create more explicit APIs and therefore, I generally prefer them over method overloads.
Specifically, when working with Intellisense I much prefer to see this:
Over this:
Where I may have to guess (or look up documentation) for what the value of param1 and param2 will be if I don't specify.
Optional parameters are meant to facilitate COM object interactions as COM objects use lots of optional parameters. So if you're doing P/Invoke or COM object stuff, prefer optional parameters. Otherwise, method overloading is the proper way to go as it saves a lot of confusion.
Rather than overloading or named optional parameters, I've grown to like object initializers very much. All you need in the class is a parameterless constructor, and public properties for anything you want to set on initialization.
Assuming class Bar has public string properties "Name" and "Pet", you can construct a new object like this.
var foo = new Bar { Name = "Fred", Pet = "Dino" };
The advantage is that you don't need a separate overload for each combination of values that you want to initialize.
Optional parameters require a default value (I only assume), and thus in some cases it might be difficult to supply one. Why? Well some classes need runtime information to get initialized which may not be available to the compiler.
When it comes to primitive types, the answer may have to do with if a default value can be assumed, or if the absence of a parameter might signify different behavior by the method.