When are named arguments useful?

I use named parameters to make call sites clearer and when I have parameters with default values. The default values case has been discussed in a number of different answers already, so let's talk about call site clarity.

An analysis with metasyntactic variables isn't going to highlight their usefulness. Consider, instead this more "real-world", if you will, example.

Let's look at a call site:

something.OpenFile(documentPath, true);

What is this going to do? It's going to open documentPath. And do something else? What else? I can't remember, even though I wrote OpenFile only a week ago.

Here are three different examples for OpenFile that are relatively realistic.

void OpenFile(string path, bool shouldOverwrite)
void OpenFile(string path, bool preserveExisting)
void OpenFile(string path, bool enableWriting)

With named parameters, we can make the call sites clear:

something.OpenFile(documentPath, shouldOverwrite: false);

It's pretty clear that the file will not be overwritten.

something.OpenFile(documentPath, preserveExisting: false);

It's pretty clear that the file will be overwritten if needed.

And finally, we have:

something.OpenFile(documentPath, enableWriting: false)

It's pretty clear that the file will be opened for reading only.

Could this particular example be solved with something else like an enum? Yes. Can you always change the code? No. Does everyone else have the same abiding hatred for bool parameters that I do? No. :-)

Can you over do it with named parameters? Yes. Do good local variable names help? Tremendously.


Named arguments are meant to increase readability. For example I've just used one as such

public void MarkAsDone(bool skipped) {}

Now by invoking the method without the name we have an ambiguity

MarkAsDone(true); //does true mean that it is successfully done?

Which can be resolved by clarifying with a name

MarkAsDone(skipped: true);

I think using the named parameter makes the client code way less ambiguous.

Apart from that they can be used to uniquely identify an optional parameter when there's more than one with the same type

MarkAsDone(int first, int second=0, int third=0) {}

///

MarkAsDone(1, third: 3);

Tags:

C#