Categories:

First look at C# .Net 4.0: Optional and Named Parameters

With the Release Candidate of Visual Studio 2010 released this week and an official release slated for April, I thought I’d take some time and explore some of the new features we’ll be working with in C# 4.0.  So over the course of a couple of weeks I expect to be posting my thoughts and findings on each, starting with Optional and Named parameters.

Optional and Named parameters compliment each other quite well, though they are in fact two completely separate concepts.  An optional parameter allows us in our code to specify default values for method parameters, meaning the calling code has the option to omit the parameter and opt for the default value.   Named parameters allow calling code to specify the name and the value of a parameter in the calling statement which, when used properly, can result in more explicit, readable code.

Optional Parameters

Optional Parameters are not a new concept, they’ve long been present in C++, and in fact, they’re not even a new concept in the .NET family of languages, F# allows optional parameters and I can remember using them way back in VB.NET 1.0.

Currently in C# 3.5 and below if there was a case where a default value for a particular method parameter was needed, we would achieve it with method overloading and chaining .  Say for instance we wanted to add a LineItem to an Order, and by default we would like the quantity parameter to have a value of 1.  Currently we would have to write two methods similar to this,

        private void AddLineItem(Guid productId)
        {
            AddLineItem(productId, 1);
        }

        private void AddLineItem(Guid productId, int quantity)
        {
            //Do something.
        }

This will allow us to call the same block of code in two different manners, one with a default value of 1 as quantity, and one with a specified quantity,

            AddLineItem(theProductId);    //Add line item with default quantity of 1.

            AddLineItem(theProductId, 3); //Add line item with specified quantity of 3.

With the introduction of optional parameters we can now achieve the same result using only one method, by simply declaring the default value of quantity as part of the parameter declaration.

        private void AddLineItem(Guid productId, int quantity = 1)
        {
            //Do something.
        }

 

So by declaring that the default value of quantity is 1, we are giving the calling code the option to omit the parameter and the method will be called with the default value.

One thing to remember when using this approach is that the default value needs to be a compile time constant.   For instance I thought it would be nice to be able to set a DateStamp parameter to default to the current date and time,

        private void AddLineItem(Guid productId, int quantity = 1, DateTime dateStamp = DateTime.Now)
        {
            //Do something.
        }

 

But this will give you a compiler error, Default parameter value for ‘dateStamp’ must be a compile-time constant. But as a work around and using the option parameters feature I managed to come up with another way of doing it without adding an overload,

        private void AddLineItem(Guid productId, int quantity = 1, DateTime dateStamp = null)
        {
            if (dateStamp == null)
                dateStamp = DateTime.Now;

            //Do something.
        }

Not as elegant as I originally intended, but the desired result is achieved.

Named Parameters

Named parameters allows calling code to couple the value of a parameter to the name of the parameter, although this will increase the readability of code, I can also see some coupling problems, in that, if for instance you decide to rename your parameters, your going to cause the code that is using named parameters to break.  So it’s a bit of a trade off between readability and maintainability.  None the less, it is useful/vital when dealing with optional parameters and you wish to omit some parameters and not others.

Say for instance I wanted to call the AddLineItem method above, and I wanted to provide a datestamp value, but omit a quantity value.  Using named parameters I could achieve this with the following code,

            //Add line item with a specified datestamp and a default quantity.
            AddLineItem(theProductId, dateStamp: yesterdaysDate);

 

Using named parameters I could also swap the order of the parameters I’m providing around.  I’m not sure why you would choose to do this, but none the less it’s possible,

            //Add line item with parameters order swapped around.
            AddLineItem(quantity: 5, dateStamp: yesterdaysDate, productId: theProductId);

 

Although I agree it does make the code more readable, I would probably try to avoid using named parameters for any case other than the optional parameter scenario as, like I said earlier in the post, it results in a coupling between the calling code to the name of the parameter.  You never want to be in a position where you’re avoiding changing the names of parameters because your worried about the effect it will have on the wider code base.

  • Share/Bookmark

Posted in Code.

Tagged with , , , .


4 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. anon says

    The rational for not introducing optional parameters in C# until now was that that the default value is compiled into the calling assembly. That means when you change a default value in a library you have to recompile everything that depends on it. While optional parameters are surely useful that really looks like a serious problem.

    We have the same problem with constants. Constants are compiled into the assembly that uses the constant. Changing a constant in a library doesn’t change the values in the code that uses this library. This is why your constants should be internal and public variables should be static readonly. Even definitions of mathematical constants like e can contain typos.

    So please, if you are developing a library be very careful about this new feature. For classes this feature seems to be safe though. There isn’t any compile time constant other than null so it is quite impossible to ever change the default value.

  2. Matt Long says

    Wow, that is a massive draw back. With that being the case, applying the optional parameter approach on pubic methods is actually quite dangerous.

  3. Tiny says

    What I know, named parameters are in new .NET because of interopelabitlity with components which have optional parameters, like COM interoperability. Imagine function in Office Automation with 20, 30 params where you have to specify Type.Missing all the time, and you are actually sending there just 1, 2 paramters.

    Named parameters make such code much, much more readable.

Continuing the Discussion

  1. CAMERON linked to this post on June 24, 2010

    Medicamentspot.com International Legal RX Medications. Special Internet Prices (up to 40% off average US price). NO PRIOR PRESCRIPTION REQUIRED!…

    Combivir@buy.online” rel=”nofollow”>.…



Some HTML is OK

or, reply to this post via trackback.