C# Optional Parameters or Method Overload?

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: 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 mscorlibSystem. Object { .

Method public hidebysig specialname rtspecialname instance void .ctor() cil managed { . Maxstack 8 L_0000: ldarg.0 L_0001: call instance void mscorlibSystem. 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 } }.

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: 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 mscorlibSystem. Object { .

Method public hidebysig specialname rtspecialname instance void .ctor() cil managed { . Maxstack 8 L_0000: ldarg.0 L_0001: call instance void mscorlibSystem. 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 } }.

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.

This is a nice feature, but it requires your objects to be mutable. I tend to prefer immutable types wherever possible. – hemp May 25 at 23:24 Immutable and mutable both have their place, and in C#, enforcing immutability can require more work than readonly properties and private setters.

Any "change" requires constructing a new object and returning it in place of the original. So, as in most things, "it depends. " – Cylon Cat May 25 at 23:28.

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.

3 @hemp using optional parameters creates ambiguity. You end up with one method that does many things. The method will have different behavior based on it's input.

A method should do one thing and one thing only. – Chuck Conway May 25 at 23:30 1 @Chuck I disagree wholeheartedly, which is why I started by saying the question is subjective in nature. Further, the argument for "a method should do one thing and one thing only" is a tired one and oft abused.

Worse, the most common implementation pattern I see for overloaded methods is to have one overload call the other, passing in a default value. – hemp May 25 at 23:42 1 @hemp using an overloaded method to set a default, is encapsulating and isolates the difference from the implementation. There is no ambiguity in this approach.

– Chuck Conway May 25 at 23:49 1 @Chuck It is not possible to resolve the 'ambiguity' issue because that is purely subjective. However, using an overloaded method to set a default violates your position against having branching logic within a method because the ultimate callee in that scenario behaves differently based on the value passed in. – hemp May 25 at 0:10 1 While I agree that the "one thing only" method is a thing of computer science courses, the extraction of multiple overloaded method does make sense.

Each overload is/should be treated as a use case that has distinct parameter validation and possibly even logic. Like mentioned, it is largely suggestive, but I find having succinct use cases for optional parameters as a kludge and means to provide a nest for the development of some interesting bugs. It is much easier to test a series of overloads than to come up with all the possible permutations of optional parameters in a lot of cases.

– joseph. Ferris May 25 at 14:48.

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.

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.

Preferable to optional parameters. Clear in purpose. Should do one thing well.

Of a method. Start using inheritance. Harder to work with.

Preference to optional parameters.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions