When C# 4.0 was released, developers got their hands on some syntactic sugar that helps in the readability and maintainability of code – optional arguments and named arguments.
Optional Arguments
The first concept we’ll be looking at today is optional arguments. Let’s use optional arguments to help a common maintainability issue – adding another argument to a function. Here’s a really basic method that we’ll be extending.
{
Console.WriteLine("Parameter a is: {0}", a);
}
…
MyFunction(3);
// Output: Parameter a is: 3
At some point in the future, as often happens, a developer decides MyFunction needs to do a little more and needs another argument.
{
Console.WriteLine(a);
Console.WriteLine(b);
}
This introduces a maintainability problem – everywhere that MyFunction is called now needs to supply another argument. What the developer can do instead is assign argument “b” a default value.
{
Console.WriteLine("Parameter a is: {0}", a);
Console.WriteLine("Parameter b is: {0}", b);
}
…
MyFunction(3);
// Output: Parameter a is: 3
// Output: Parameter b is: 4
With the use of optional parameters none of the calling code needs to change, and the developer can be at least a little more confident that she didn’t break existing code.
There’s no limit to the types that can be used in optional parameters. Let’s extend our method again by adding an optional string parameter.
{
Console.WriteLine("Parameter a is: {0}", a);
Console.WriteLine("Parameter b is: {0}", b);
Console.WriteLine("Parameter c is: {0}", c);
}
This function can now be called three different ways.
// Output: Parameter a is: 3
// Output: Parameter b is: 4
// Output: Parameter c is: foo
MyFunction(3, 5);
// Output: Parameter a is: 3
// Output: Parameter b is: 5
// Output: Parameter c is: foo
MyFunction(3, 5, "bar");
// Output: Parameter a is: 3
// Output: Parameter b is: 5
// Output: Parameter c is: bar
So now what happens if a caller wants to use MyFunction and only supply values for “a” and “c”. This is now possible with the use of named arguments.
Named Arguments
Using named parameters, let’s call the previous function and supply values for “a” and “c”.
// Output: Parameter a is: 3
// Output: Parameter b is: 4
// Output: Parameter c is: bar
As you can see, named arguments are used by supplying the name of the argument, a colon, and then the value you’d like to supply for that argument. If you don’t supply a name, like I did in this case, they will be assigned in the order they appear in the method signature.
We could also reorder the arguments, if we wanted.
// Output: Parameter a is: 3
// Output: Parameter b is: 4
// Output: Parameter c is: bar
One of the best uses I’ve seen so far for named arguments is to improve readability. Here’s an example of code that has poor readability.
0.1,
2.4,
1.7,
0.0,
10.3,
2.3,
1.0,
0.0,
0.0);
I’m sure we’ve all seen something similar to this. What the heck are those values supposed to mean. Using comments for every value would help, but another solution is to name each argument.
positionX: 0.1,
positionY: 2.4,
positionZ: 1.7,
velocityX: 0.0,
velocityY: 10.3,
velocityZ: 2.3,
accelerationX: 1.0,
accelerationY: 0.0,
accelerationZ: 0.0);
This is much more readable. We can see clearly that this Update function is used for some physical properties of an object and we can clearly see where each value is being applied.
That does it for this tutorial on optional and named arguments. Hopefully you can see where this syntax would be useful in your own systems and you begin using them to create higher quality code. If you’ve got any questions or comments, please leave them below.