Title: Use named and optional parameters in C#
Optional parameters is one of the few additions in recent versions of Visual Studio that are really useful. I usually try to post examples in an older version of C# because it's easier for someone to move an older example to a more recent version than it is to move a recent example to an older version. Most of the C# language has remained unchanged for a long time, so this isn't a problem. However, C# includes are a few useful features that were added relatively recently.
Named and optional parameters were added with C# 2010.
Named arguments let you use the names of parameters when you invoke a method. For example, suppose the Person class has a constructor that takes the parameters: name, address, email, sms_phone, voice_phone, and fax. Then your code could invoke the constructor like this:
Person person = new Person(name: "Rod Stephens",
email: "RodStephens@CSharpHelper.com",
address: "", sms_phone: "", voice_phone: "", fax: "");
This makes your code a bit more self-documenting, particularly if the parameter list is long. It also allows you to specify arguments in any order you wish.
While named arguments provide some benefit, they're really not all that exciting until you combine them with optional parameters. To make a parameter optional, follow it with a default value in the method's declaration. For example, the following code shows Person class's constructor with the address, email, sms_phone, voice_phone, and fax parameters optional.
public Person(string name, string address = "", string email = "",
string sms_phone = "", string voice_phone = "", string fax = "")
{
Name = name;
Address = address;
Email = email;
SmsPhone = sms_phone;
VoicePhone = voice_phone;
Fax = fax;
}
Now the program can use the following code to create a new Person object while specifying only the name argument (which is required because it doesn't have a default value in the constructor's declaration) and the email argument.
Person person = new Person(name: "Rod Stephens",
email: "RodStephens@CSharpHelper.com");
This is not only handy, but it also gives you a new capability that you didn't have before. Suppose you want the constructor to require name but not the other parameters. Without optional parameters, you could make several overloaded versions of the constructor, one that takes (name), one that takes (name, address), one that takes (name, address, email), and so forth.
That would let you create Person objects while omitting some of the arguments, but it would not let you omit them in any combination. For example, you could not specify name and email without address. Even if you were willing to make overloaded constructors for all of the 32 possible combinations (if I've counted correctly), the compiler couldn't tell all of the versions apart because all of the arguments are strings.
Named and optional parameters let you provide and omit arguments in any combination you want with only a single constructor.
Optional parameters are also useful for setting default values easily. For example, without optional parameters you could provide a version of the constructor that takes values for all parameters and then use a second version similar to the following code to pass it default values for arguments that are omitted.
public Person(string name)
: this(name, "????", "????", "????", "????", "????")
{
}
This works, but again only lets you handle certain combinations of omitted arguments and requires many different versions of the constructor.
Another approach would be to let the calling code pass null or some other value to "omit" arguments and then make the code check each one to see if it is null as in the following code.
public Person(string name, string address, string email,
string sms_phone, string voice_phone, string fax)
{
Name = name;
if (address == null) Address = "????";
else Address = address;
if (email == null) Email = "????";
else Email = email;
if (sms_phone == null) SmsPhone = "????";
else SmsPhone = sms_phone;
if (voice_phone == null) VoicePhone = "????";
else VoicePhone = voice_phone;
if (fax == null) Fax = "????";
else Fax = fax;
}
This is a lot more cumbersome and inelegant than using named and optional parameters.
To summarize, named and optional parameters are particularly useful when:
- A method has lots of parameters and you want to use names to help document the calling code
- You want to provide default values for parameters
- You want to let the calling code omit arguments in any combination
Download the example to experiment with it and to see additional details.
|