Optional Parameters in C# 4.0

In the last post we saw dynamic typed object in C# and as we saw earlier the upcoming features of C# 4.0, Today we are going to look at Optional Parameters.

Let’s say I have a class Employee and I provide few overloads of constructor to enable make certain parameters as optional as follows:

 public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Qualification { get; set; }
public string MiddleName { get; set; }

public Employee(string firstName, string lastName)
{
FirstName= firstName;
LastName= lastName;
Qualification= "N/A";
MiddleName= string.Empty;
}
public Employee(string firstName, string lastName, string qualification)
{
FirstName= firstName;
LastName= lastName;
Qualification= qualification;
MiddleName= string.Empty;

}
public Employee(string firstName, string lastName, string qualification,
string middleName)
{
FirstName= firstName;
LastName= lastName;
Qualification= qualification;
MiddleName= middleName
}
}

With C# 4.0, you need to create just one constructor for that and that is

public Employee(string firstName, string lastName,
string qualification = "N/A", string middleName = "")
{
FirstName= firstName;
LastName= lastName;
Qualification= qualification;
MiddleName = middleName;
}

as simple as that 🙂 and you can easily call that like Employee(“Adil”,”Mughal”);

This feature was available in some other languages but was for some reason not provided in C# till yet but now it’s available. This feature has good impact in COM interop which allows developers to skip missing parameters which we will hopefully see in later post(s). Finally, the compiler will always fill the optional parameters by their default given values, if you do not provide them. For instance, In our current case it will be:

Employee(“Adil”, “Mughal”, “N/A”, “”);

Simple but useful feature!

  • Tooba Zafar

    Good work Adil 🙂

  • Thanks Tooba!

  • Thats Great…

    The material above is really informative…

    Good work…

  • Wouldn’t the orginal code look more like this?

    public class Employee
    {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Qualification { get; set; }
    public string MiddleName { get; set; }

    public Employee(string firstName, string lastName)
    : this(firstName, lastName, “N/A”, string.Empty)
    {
    }

    public Employee(string firstName, string lastName, string qualification)
    : this(firstName, lastName, qualification, string.Empty)
    {
    }

    public Employee(string firstName, string lastName, string qualification, string middleName)
    {
    FirstName = firstName;
    LastName = lastName;
    Qualification = qualification;
    MiddleName = middleName;
    }
    }

  • Anonymous

    I had resigned myself to the extra maintance costs of overloads… glad this feature has finally been added.

  • This is fabulous! Overloaded methods are ok, but I get tired of making sure I’ve covered all the variations I need. Looking forward to optional parameters!

  • I completely agree that this is definitely needed and wanted option! This will absolutely help with code maintenance and lower potential bug issues.

  • Anonymous

    Yay! Another great, ages-olde VB standard Productivity Feature finds its way to the upstart 🙂

    Keep them coming… eventually we’ll have all of what made Visual Basic the (still) most used programing tool in the world.

    btw: I’m a C# person now… but I will always respect VB.

  • This is really great news. When I first started working in C#, I was puzzled by the ommission of this seemingly basic feature, and worked around it in very much the way described by Bobby Cannon above. I like overloading constructors as much as the next guy, but why write three constructors when one will do?

    Can’t wait…

    Chris

  • Anonymous

    The parameters can also be passed out of method’s signature order. Eg:

    Employee e = new Employee(lastName: “Name”, firstName: “My”, middleName: “Middle”)

  • @Anonymous Respect VB???? VB to me is the Sega Saturn of .NET languages. It’s a language that purpose was for hobbyists to be able to program for retrofitted into the modern .NET framework. Just as the Saturn was an amazing 2D machine retrofitted to be a modern 3D machine.

  • Anonymous

    For the ridiculous lists of optional parameters in Office Automation COM interop, a solution has been available since .NET 1.0 – merely generate your own assembly and change the declaration to parameter object[] p

    Optional parameters are a mild convenience at best, and a mild hazard (they afford yet another opportunity for implicit behavioural dependencies likely to cause breaking changes across versions)

  • Anonymous

    It was time that C# copy that old and important feature from other languages. Thanks.

  • Anonymous

    Not sure how I feel about these fundamental changes to the language. In fact, I’m pretty sure I won’t be using any of them unless the _need_ arises; I’ll stick with C# 2.0 language specifications, maybe with some LINQ thrown in if I’m in a good mood.

    VB was a powerful language and had its own quirks. I hate to see the only difference between C# and VB become curly braces and semicolons.

  • This comment has been removed by the author.

  • Anonymous

    Finally… This was the one thing that stopped most of my C# migration projects before they even started…
    THANKS to Microsoft for at last listening.

  • Employee(“Adil”, ”Mughal”);
    this is ok, but what if i want to call only 1st, 2nd and 4th parameter, while the 3rd will be defaulted? is it something like this:
    Employee(“Adil”, ”Mughal”, , “M”);

    or there is no way and i have to specify the 3rd argument:
    Employee(“Adil”, ”Mughal”, “N/A”, “M”);

    or something completely different?

  • @Dragan

    You will call it new Employee(firstName: “Adil”, lastName: “Mughal”, middleName: “A.”).

    @All
    Yes, this is a great feature. However, I’m a bit disappointed that the default parameters are available for value types only. Having ability to pass “null” as a default for reference types would be great.

  • Lol, I’m a Dyanmics Ax programmer and I wondered all the time why this was available in X++ and not in C#… it’s finally in there now. Great!

  • Anonymous

    I quickly got over the omission of optional params with the following notation:

    Employee newEmp = new Employee()
    {
    FirstName = firstName,
    LastName = lastName,
    Qualification = qualification,
    MiddleName = middleName
    }

    of course this throws integrity out the window and requires the consumers of the code to know what they’re doing, but when I’m the only one involved, that doesn’t bother me too much, as the bases are covered. 😀

  • The really interesting question is: does the C# compiler “burn in” the default parameter values on the caller’s side or is it choosing the right parameter value from the callee’s signature at the call time?
    This is relevant from the code versioning perspective, say, if v2.0 of the assembly has different default parameter values.

    Cheers

  • Who said anything about only passing value types? A string is an object, you should be able to pass null as a default value… for example:

    public Employee(string firstName, string lastName, string qualification = null, string middleName = null){ FirstName= firstName; LastName= lastName; Qualification= qualification; MiddleName = middleName;}

    which would pass

    Employee(“Adil”, “Mughal”, null, null);

  • This is seriously one of the worst features I have ever seen. It has taken years since the first release of .NET to convert people over to overloading and now they are bringing back one of the worst possible things!!!

    Tell me, how do I know if “N/A” was set by the user or if it is the default from the optional?? Answer: You don’t and that is BAD!!

    Microsoft have some incredible and smart but stupid people working for them. I can’t believe that they wasted money on such a dubious ‘feature’.

  • Anonymous

    For the two optional parameters, first is “N/A” and the other is just “”. Does it makes any difference? Can I give reverse such that “” and “N/A” or all the parameters “N/A” or just “”?

  • Anonymous

    Finally,… in Delphi we could do this ages ago!

    Stephan

  • I like the idea of optional parameters, but C#3.0 intializers solve this problem also for the most some part. You could opt to only provide mandatory arguments as a constructor. And set the rest using properties when needed.

    Eg.

    public Employee(string firstName, string lastName)
    {
    FirstName = firstName;
    LastName = lastName;
    Qualification = “N/A”;
    MiddleName = string.Empty;
    }

    And use it like this:

    new Employee(“myFirstName”, “myLastName”){Qualification = “My Qual”};

  • Icey

    @RaimondB this approach is elegant, but you can only use it for actually constructors. If I get it right, you can use this approach for any method… right?

  • Anonymous

    I think this is at last a step gone forward, for those programmers thinking this is a bad idea, wait until you create a class or function with 5 to 10 overloads.. yes it doesn’t happen every day and only in very extreme cases, but managing one constructor with a few optional values is way easier than trying to manage 5 or more…. same goes for functions, if you think that there is something wrong with writing 10 overloads, just look at Convert.ToString(“36”); 36 overloads..
    it happens..

  • @Icey: yes will only work for constructors.
    Don’t get me wrong, I’m also glad that we will get this feature.
    I just wanted to clarify that the constructor problem is not so big. And that the value of optional parameters will be mostly is having less method overloads.

  • Gode

    At last you have included this feature. I was wondering why it was not included in older versions of .NET but now we have it. Thank You!

  • I don’t think the optional parameter syntax offers any real advantage to the overload syntax on its own. I think something very important that is missing from this blog post is the concept of named parameters and their relationship to optional parameters. Together the two offer some capabilities that simple function overloading syntax does not. With named parameters and optional parameters together, one can now create much more flexible code with a lot less code that is very readable. As a former VB developer (now C# developer) I was dead set against optional parameters, but with the patterns that come about with named parameters I think it is a positive addition to the language.

  • @Jason: Yes you are right. The concept of named argument is mentioned in another post 🙂

    Plese visit : http://adilamughal.blogspot.com/2009/04/c-40-named-argument.html

  • Anonymous

    Finally … now those VB guys don’t have anything left to mock us ;).

  • Anonymous

    Why can’t C# have true optional parameters like C++ does.

    public void FunctionName(int item, int item2, int item3=0, String name=String.Empty)
    {
    // do stuff
    }

    ?????

  • Anonymous

    being an old c++/java programmer, i really dislike the subtle transition from a decent typed language to essentially vb principals integrated into old stable c#. not only this feature, but dynamic variables and a few other things i’ve seen pop up on the radar.

    Nothing that hurts me directly, i can avoid what i dont like. But our junior programmers will have to be put on a short leash after c# 4.0 is released. i’m afraid these features will be misused in an attempt to demonstrate their “understanding” of the new c# 4.0 more than they will be used properly in the rare cases where they make sense.

  • GregW

    Paul commented:

    ‘Tell me, how do I know if “N/A” was set by the user or if it is the default from the optional?? Answer: You don’t and that is BAD!!’

    The correct answer is that if you care about whether you got the N/A as a result of an explicit vs default argument, you’re doing something wrong.

  • Great news! No more junky duplicated code just because something has to be overloaded 10x. What a waste of time to change the code in ten places! This has always been available in VB. Just common sense.

  • Rajkumar

    Correct me if i’m wrong the above functionality can be done
    if the functionality of all overloaded functions is almost same else if the functionality it self is different according to method signature then i hope it shud b inscribed in a if else loop which is again looks like a performance head.

    I have understood the syntax of it but can u xplain me how it will impove performance by any case…

  • Well, it’s good to see that VB.NET and C# are finally growing together.

    If your are currently calling a VB.NET function with optional parameters from C# you will run into trouble.

  • This feature has been there in c++ since ages

  • Max

    At last! Very important feature that cuts a lot of unnecessary code. Feature should have been introduced in c#’s first version.