11

A long time ago I programmed a lot in ADA, and it was normal to name arguments when invoking a function - SomeObject.DoSomething(SomeParameterName => someValue);

Now that C# supports named arguments, I'm thinking about reverting to this habit in situations where it might not be obvious what an argument means.

You might argue that it should always be obvious what an argument means, but if you have a boolean argument, and callers are passing in "true" or "false" then qualifying the value with the name makes the call site more readable.

contentFetcher.DownloadNote(note, manual : true);

I guess I could create Enums instead of using true or false (Manual, Automatic in this case).

What do you think about occasionally using named arguments to make code easier to read?

4
  • Parameter comment on top of methods also helps. Feb 28, 2011 at 12:16
  • 1
    @amir-rezaei: Parameter comments on top of methods only help if you can trust the comments. Unless you have good developers and good code review processes, I wouldn't trust the comments.
    – btilly
    Feb 28, 2011 at 18:44
  • As a one-time Ada user myself, I'm for occasional use as you describe. That's how I remember them being used in Ada, BTW - I wouldn't call it "abnormal", but the word "normal" seems to imply most calls would specify parameter names, which isn't how I remember things. Of course conventions vary, but unnecessary clutter is a bad convention in any language IMO.
    – user8709
    Feb 28, 2011 at 21:16
  • I agree re your use in Ada - it wasn't something we did all the time, but where it helped.
    – Damian
    Feb 28, 2011 at 23:55

5 Answers 5

7

This was suggested in the development of C++, and Stroustrup discusses it in his "Design and Evolution of C++", pages 153 and following. The proposal was well-formed, and drew on prior experience with Ada. It wasn't adopted.

The biggest reason was that nobody wanted to encourage functions with large numbers of parameters. Each additional feature in a language costs something, and there was no desire to add a feature to make it easier to write bad programs.

It also raised questions of what the canonical parameter names were, particularly in the usual header and code file convention. Some organizations had longer and more descriptive parameter names in the .h file, and shorter and easier to type names in the .cpp file (substitute file suffixes as desired). Requiring that these be the same would be an additional cost on compilation, and getting names mixed up between source files could cause subtle bugs.

It can also be handled by using objects rather than function calls. Instead of a GetWindow call with a dozen parameters, create a Window class with a dozen private variables, and add setters as necessary. By chaining the setters, it's possible to write something like my_window.SetColor(green).SetBorder(true).SetBorderSize(3);. It's also possible to have different functions with different defaults that call the function that actually does the work.

If you're just worried about the documentation effect of contentFetcher.DownloadNote(note, manual : true);, you can always write something like contentFetcher.DownloadNote(note, /* manual */ true);, so it's not even very helpful in documentation.

1
  • Funnily enough when I moved from Ada to C, I started using the convention you describe - code reviewers hated it though. Agree re not using it for large numbers of parameters.
    – Damian
    Feb 28, 2011 at 22:38
7

I think this is issue of making bad code more readable, rather than “best practice”.

Having a method (or contractor) that takes 20 parameters is a “bad smell” and is likely to be due to a problem in your design. However if I am forced to work on code when methods take a lot of parameters, then named parameter make the code less hard to understand.

When methods only have 1 or 2 parameters and it is clear from the method name what the parameter are, then named parameter add nothing. This is the ideal case to be in.

If all the code you work on is written as par the “clean code” book, then you will have very little use for named parameters, however we live in the real world.

2
  • 1
    A function with two parameters can be confusing, if both parameters are the same type and with no clue to which is which. Of course you can name the function in a way that provides that clue, but you're really just doing what the parameter names do anyway - except that you make it compulsory to include that verbosity even when the context (e.g. the expressions that supply the parameters) make it obvious which parameter is which.
    – user8709
    Feb 28, 2011 at 21:19
  • 1
    @Steve314 Example: void TrackDataChange(Data oldData, Data newData)
    – Alexander
    Jul 12, 2019 at 13:53
3

I agree that adding the parameter name makes it more readable. However, most of the books I've read seem to consider boolean switches to be a bad practice. I sometimes do this:

public Content DownloadNote(Note note)
{
    return downloadNote(note, manual: false);
}

public Content DownloadNoteManually(Note note)
{
    return downloadNote(note, manual: true);
}

That does give you more flexibility when implementing your API. It also allows you to control the case where you have multiple boolean switches, but not all of them can be active at the same time.

5
  • 3
    If you have x choices, will you make 2^x frontends?
    – apoorv020
    Feb 28, 2011 at 14:34
  • @apoorv020 - if I had enough parameters to a method call that 2^x became significant, I'd make a new class to hold the parameter values, and just pass one parameter. Feb 28, 2011 at 18:25
  • @scott-whitlock: Option 1 - create an object, set x properties, call a method once with your object. Option 2 - call a method with x named parameters. Which is better depends on your language. In a dynamically typed language, option 1 requires significantly more boiler-plate with no gain, and so is worse. In a statically typed language you still add the boilerplate, but tests for incorrectly named keys get to be done at compile time rather than run time. Therefore option 1 is better in C#, but option 2 is a clear win in Python.
    – btilly
    Feb 28, 2011 at 18:40
  • @btilly - as Ian pointed out, Clean Code clearly tells you not to have functions with more than 2 or 3 parameters. To be fair, it was dealing with Java, which is statically typed. The OP is also asking about C#, which is statically typed. I would still prefer to use function overloads and/or different precisely named function names than a long list of parameters. Feb 28, 2011 at 20:06
  • @scott-whitlock: Do we actually disagree? We agree on what is best in C#. We both know what Clean Code says. My point was that it is important to understand why it is good, so that you know when the advice does or does not fit a different environment.
    – btilly
    Feb 28, 2011 at 22:48
3

I'm a big believer in named parameters in situations where the types and semantics are not clear from the name of the method. My experience is that few folks read the documentation.

That being said, named parameters should not be an alternative to making sensible argument lists, using helper objects (to "tie" together semantically related arguments), and using enumerations where relevant.

0

I think this is more useful in non-OO languages, where you may have one function that has to do something in several slightly different ways, and the way it determines what to do is based on parameter values. In the OOP world, we would just overload the function, but when that's not possible then you wind up passing a bunch of flags (or a bunch of values, and whether or not they're passed is the flag).

I think it's more readable, to an extent; but as others have mentioned, having many parameters is a code smell, so I don't see a whole lot of use for this in an object-oriented language like C#.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.