Nov 10

C# 4.0: named parameters

Posted in C#      Comments Off on C# 4.0: named parameters

After several failed tries, I finally managed to configure my home PC so that it runs the Server 2008 image (with the first preview of .NET 4.0) and just with a reasonable enough delay. Ok, since I”m finishing writing a book on C# 3.0 (with my good friend Paulo), I thought that I should start by looking at C# 4.0. As has been said, C# 4.0 will be mostly on dynamic programming features. To start my study, I”ve just picked a random feature: named parameters.

The first thing I”ve noticed while running some tests on this feature is that C# is becoming closer to VB.NET. If things keep going this way, in a few years the only difference will be in blocks: VB.NET will have the typical begin end blocks and C# will remain with the traditional { } symbols:,,). Didn”t Joel wrote something about that in 2001?

But I digress…so, today is all about named parameters. What can I do with named parameters? Basically, you can pass a value to a parameter by name, instead of using its position. Lets start with a simple example…consider the following class:

class Student    {
        public String FirstName { get; private set; }
        public String LastName { get; private set; }

        public void ChangeName(String firstName, String lastName)
            FirstName = firstName;
            LastName = LastName;

Until now, you could only pass values to parameters based on their position:

var std = new Student();
std.ChangeName( “Luis”, “Abreu” );

Starting with the next release, you”ll also be able to use the name of the parameter to assign its value. Here”s an example of how you could write the previous snippet with named parameters:

std.ChangeName(lastName: “Abreu”, firstName: “Luis”);

Do notice that in both cases you need to pass both values because none has a default value. Yes, with C# 4.0 you”ll also be able to set up parameter”s default values. Lets change the previous example to show how you could do this:

public void ChangeName(String firstName, String lastName = “Abreu”) {
//some code as before

Setting default values makes the associated parameters *optional*. This is important because until now this feature wasn”t supported in C# (in previous versions, you had to use overload methods for simulating this). What this means is that you could call the previous method and only pass the parameter which doesn”t have the default value:

std.ChangeName(firstName: “Luis”);

You should also keep in mind that optional parameters must come last (yes, really at the end, after everything else – this includes ref and out parameters too!). One additional observation: you didn”t really need to use the parameter name because the mandatory parameter (ie, the one whose value you had to set) was the first one. So, you could simply write:


What this means is that most of the time, you”ll use the named parameter approach for setting the value of some optional parameters. What happens when you write the previous method call? Well, the compiler will pick up the defaults and pass them to that method call. In other words, the compiler will copy the values of the default values you assigned to the parameters and will add them to the method call when those parameters aren”t explicitly set. So, when the compiler finds the previous method call, it will replace it with this:

std.ChangeName(“Luis”, “Abreu”); //Abreu is used as default value for lastName

Notice that you”ll be able to use optional and named parameters with constructors and indexes.

Now that we have these new features, it”s time to see what happens with overload resolution. What happens when we add another method which receives only one parameter? For instance, suppose the class also has this method:

public void ChangeName(String firstName) {
            FirstName = firstName;

Which method will be called when you write std.ChangeName( “Luis” ); ? The new features doc says that

“A signature is applicable if all its parameters are either optional or have exactly one corresponding argument (by name or position) in the call which is convertible to the parameter type.

Betterness rules on conversions are only applied for arguments that are explicitly given – omitted optional arguments are ignored for betterness purposes.

If two signatures are equally good, one that does not omit optional parameters is preferred.”

So, the last method should be picked in the previous scenario. That doc has a few more examples which you should look at if you want to have 100% understanding of overload name resolution with named and optional parameters. If you do lots of COM interop, then you”ll really love these new features. However, there”s still some controversy surrounding its use. In fact, I still remember reading this post on why C# didn”t allow for optional parameters. It made sense, though the option of having optional parameter was also valid. I think I”ll have to play a little more with it to make my mind. Keep tuned for more on the next version of C#.