Named and optional parameters in C# 4.0

One commonly heard grievance about C# was how it did not support optional parameters. Well C# 4.0 not only has that, but you can also specify parameters by name.

Consider the following two examples :

public void RepeatText(string text, int count = 3)
{
    while (count-- > 0)
    {
        Console.WriteLine(text);
    }

    Console.WriteLine();
}

public void RepeatDecoratedText(string text, string decoration = "Mr.", int count = 3)
{
    while (count-- > 0)
    {
        Console.WriteLine("{0} {1}", decoration, text);
    }

    Console.WriteLine();
}

RepeatText has an optional parameter count with a default value of 3, while RepeatDecoratedText has two optional parameters. The MSIL generated for these methods are as follows (simplified, and not exact) :

.method public void RepeatText(string text, [opt] int32 count)
{
    .param [2] = int32(3)

.method public void RepeatDecoratedText(string text, [opt] string decoration, [opt] int32 count)
{
    .param [2] = string('Mr.')
    .param [3] = int32(3)

[opt] is a parameter attribute that indicates that this parameter is optional and that the default value will be specified by .param entries. These methods can now be called as follows:

RepeatText("Nish");
RepeatText("Ant", 2); 

The compiler generates code with the optional values filled in as needed:

RepeatText("Nish", 3); <-- 2nd param set via .param value
RepeatText("Ant", 2); <-- No extra work needed

You can also now pass an argument by name. This is particularly useful when you want to skip some optional args, but provide others.

RepeatDecoratedText("Nish", count: 2);
RepeatDecoratedText(count: 2, text: "Ant");
RepeatDecoratedText(decoration: "The super", count: 2, text: "Ant");

That gets compiled as:

RepeatDecoratedText("Nish", "Mr." 2);
RepeatDecoratedText("Ant", "Mr.", 2);
RepeatDecoratedText("Ant", "The Super", 2);

So basically, the parameters are either filled in via the named values provided or via the default optional values. Note that you can write optional value methods using attributes too. Example:

public void RepeatTextDuplicate(string text, [Optional, DefaultParameterValue(3)] int count)
{
    RepeatText(text, count);
}

// . . .

RepeatTextDuplicate("Nish");
RepeatTextDuplicate("Nishant", 5);

The MSIL generated for this method is identical to what you’d have got with the direct C# syntax (used earlier).

As with dynamic types, apparently the biggest beneficiaries of these new named and optional parameter features are developers who interop with Office. Just like in VBScript you can now avoid having to provide optional arguments, and can also provide a named argument directly. For others, optional parameters will definitely help reduce the number of method overloads you need to write, and where there are methods that have more than a few optional parameters, the ability to call them by specifying named parameters will result in cleaner and more legible code.

Advertisements

3 thoughts on “Named and optional parameters in C# 4.0

  1. I wonder, the default value of optional parameter are part of implementation, right ? That means, if I compile with library version 1.0 where default value is 1 and the someone will update the library to 2.0 and default will change to 2, my assumption about the default will become invalid. It would be better if it could be part of signature of the method and compiler would do the job by inlining the value.

    But change of default value will change the behavior silently even if it happens on compile time.

    On the other hand, the situation is currently exactly the same with method overloads.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s