Optional and named arguments
In the previous lesson a method got all its arguments in order, and none could be left out. But many appliances have a default mode. Press the button on a copier and it makes one copy. Need five? Key in the number of copies; if one suits you, leave it alone.
A method's parameters can have default values too. Here is a method that draws a line of characters. The parameters decide which character and how many times to repeat it:
Line(); // ----------
Line('*', 5); // *****
Line('='); // ==========
void Line(char symbol = '-', int length = 10)
{
for (int i = 0; i < length; i++)
{
Console.Write(symbol);
}
Console.WriteLine();
}Default values
Let's go through the declaration and the calls in order:
char symbol = '-'andint length = 10are parameters with default values. Such a parameter is called optional: you may leave out its argument.Line()passes nothing:symbolgets'-',lengthgets10, and the method draws ten hyphens.Line('*', 5)passes both arguments, so the default values are not needed.Line('=')passes only the first argument:symbolgets'=', andlengthgets its default value10.
The loop prints the character the right number of times with Console.Write, and Console.WriteLine() with no argument ends the line at the end.
Two rules apply to optional parameters:
- they come in the list after all the required ones;
- a default value must be known at compile time, such as a number, a character, a string,
trueorfalse. A variable cannot go there.
Here the copier picture is off. A copier may still hold the number of copies keyed in last time, but a method remembers nothing. The default value is filled in afresh on every call that leaves out the argument for that parameter.
Named arguments
What if you need a line of hyphens of length 3? You cannot skip the first argument by position: Line(3) does not compile, because the compiler expects a character for symbol first.
That is what named arguments are for: you write the parameter's name and a colon before the value. Such an argument goes into the parameter with that name, not into the parameter at the same position:
Line(length: 3); // ---
Line(length: 4, symbol: '+'); // ++++Let's go through both calls:
Line(length: 3)passes onlylength, andsymbolgets its default value'-';Line(length: 4, symbol: '+')lists the arguments in a different order from the declaration, and that is fine: the compiler matches them by name.
A named argument helps even when nothing is skipped. The call Line('*', length: 5) shows at once what 5 means, while with Line('*', 5) you have to remember it.
You can mix ordinary and named arguments. Put the ordinary ones first: the compiler matches them by position, from left to right.
Common mistake
An optional parameter was put before a required one:
Line('*', 5);
void Line(char symbol = '-', int length) // ✗
{
for (int i = 0; i < length; i++)
{
Console.Write(symbol);
}
Console.WriteLine();
}error CS1737: Optional parameters must appear after all required parametersThe program does not compile. Ordinary arguments fill the parameters from left to right, and you cannot skip the first parameter while passing the second. So the default value of symbol would never be used in an ordinary call. That is why optional parameters always go at the end of the list: void Line(int length, char symbol = '-').
Key points
- A parameter with a default value is optional: when its argument is left out, the method gets the default value, afresh on every call.
- Optional parameters come after the required ones, and a default value must be known at compile time.
- A named argument such as
length: 3goes into a parameter by name: you can list named arguments in any order and skip the optional parameters before them.