BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

C# Programming
.NET 4.0+

C# Optional Parameters

C# 4.0 introduces optional parameters to the language for methods, constructors, indexers and delegates. Optional arguments can be defined within a member's signature but omitted from calls to that member, in which case default values are used instead.

What are Optional Parameters?

Often your source code will include several overloaded versions of one or more members. Sometimes the overloads will be created so that different types can be passed to, and returned from, a method. In these cases, the signatures of the overloads may differ significantly. However, it is common to create a number of overloaded versions of a member where each version simply adds a parameter to the end of the signature. For example, the sample code below shows a simple method that can be used to send a message. Three overloads are present to allow arguments to be omitted and a default value for missing parameters to be used.

NB: In the sample code the sending of the message is simulated by outputting text to the console.

class MessageSender
{
    public bool SendMessage(string message)
    {
        return SendMessage(message, false, false);
    }

    public bool SendMessage(string message, bool useQuotes)
    {
        return SendMessage(message, useQuotes, false);
    }

    public bool SendMessage(string message, bool useQuotes, bool capitalise)
    {
        message = capitalise ? message.ToUpper() : message;
        message = useQuotes ? string.Format("\"{0}\"", message) : message;
        Console.WriteLine(message);
        return true;
    }
}

In situations similar to that depicted above, the code can be simplified to a single method using optional arguments. Optional arguments are included by providing default values within the member's signature. To do this, you simply add an assignment operator (=) and the default value to a parameter's declaration. If an argument is omitted from a call to that member, the default value will be used instead.

Any number of optional arguments may be added to the signature of a method, constructor, indexer or delegate. The key limitation is that the optional parameters must appear at the end of the declaration. No required parameters may be included after an optional item.

As an example, we can create the same functionality as the previous code as follows. Note the default values assigned to the useQuotes and capitalise parameters.

public bool SendMessage(string message, bool useQuotes = false, bool capitalise = false)
{
    message = capitalise ? message.ToUpper() : message;
    message = useQuotes ? string.Format("\"{0}\"", message) : message;
    Console.WriteLine(message);
    return true;
}

We can now test the new method by executing the following code, which exercises each possible type of call:

var sender = new MessageSender();
sender.SendMessage("Hello");
sender.SendMessage("Hello", true);
sender.SendMessage("Hello", true, true);

/* OUTPUT

Hello
"Hello"
"HELLO"

*/

Resolution of Overloaded Calls

It is possible to create two conflicting versions of a method where one overload has optional parameters and one does not. For example, we could add the following to the class:

public bool SendMessage(string message, bool useQuotes)
{
    return SendMessage("No optional arguments here!", useQuotes, false);
}

With both methods in existence, a call that includes two arguments becomes ambiguous. In such cases, the following rules are used to determine which member is executed:

  • The normal rules for preferred type conversions are applied to the provided arguments. In the above case, no type conversion is required so the candidates are considered equally valid.
  • If the conversion rules cannot differentiate between the candidates, preference is given to the member without optional arguments.

In the case of the sample code, this means that the member without optional arguments is executed, giving the following output for the test code:

Hello
"No optional arguments here!"
"HELLO"
9 May 2010