Optional and Named Parameters in C# 4.0

So far, C#, unlike C++, did not support optional arguments. For instance, suppose you need a function to print log a message, that can add a new line or not after writing the message. Most of the times you want a new line, so you don’t want to specify that for most of the calls. Until now, the only possibility was using overloaded functions, with different parameters.

class Logger
{
   public void LogMessage(string error, bool addNewLine)
   {
      Console.Write(error);
      if (addNewLine) Console.WriteLine();
   }

   public void LogMessage(string error)
   {
      LogMessage(error, true);
   }
};

class Program
{
   static void Main(string[] args)
   {
      Logger log = new Logger();
      log.LogMessage("trying to connect...", false);
      // do more stuff here
      log.LogMessage("SUCCESS");
   }
}
trying to connect...SUCCESS
Press any key to continue . . .

C# 4.0, that will be released with Visual Studio 2010, and is for now available with the Visual Studio 2010 CTP, supports, just like C++, optional arguments. So instead of using overloaded functions, you can specify a default value for a parameter. When doing the call, if you don’t provide a value for the argument, the default one will be used.

The Logger class below is identical from the functionality point of view with the one above. (The previous Main() function doesn’t have to change.)

class Logger
{
   public void LogMessage(string error, bool addNewLine = true)
   {
      Console.Write(error);
      if (addNewLine) Console.WriteLine();
   }
};

The only restriction is that optional parameters have to appear in the function after all required parameters. In other words, this is not legal:

class foo
{
   public void func(int a, int b = 0, int c)
   {
   }
}
error CS1737: Optional parameters must appear after all required parameters

Considering this implementation of foo

class foo
{
   public void func(int a, int b = 0, int c = 1)
   {
   }
}

the following calls can be made:

var f = new foo();
f.func(42, 3, 4);          // f.func(42, 3, 4)
f.func(42);                // f.func(42, 0, 1)
f.func(42, 100);           // f.func(42, 100, 1)

But this is not all. C# 4.0 brings another feature: named parameters (and this does not exist in C++). It means that when you make a call, you can specify an argument by its name, not by position. In this case you use the parameter’s name followed by ‘:’ and the value. Here are several examples:

var f = new foo();
f.func(42, c: 4);          // f.func(42, 0, 4)
f.func(42, c: 4, b: 3);    // f.func(42, 3, 4)
f.func(c: 3, a: 1, b: 2);  // f.func(1, 2, 3)

Of course, this can be used regardless the function has optional parameters or not. However, I would not use this feature for anything else than specifying an optional parameter when I would have to first suply values for other several optional parameters. In other words:

var f = new foo();
f.func(42, c: 4);          // this is good, skip b, provide value for c
f.func(42, c: 4, b: 3);    // don't like this, rather call f.func(42, 3, 4)
f.func(c: 3, a: 1, b: 2);  // don't like this, rather call f.func(1, 2, 3)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.