Put boolean arguments last

Whenever I see a method call like this:

Enum.TryParse(stringRepresentationOfEnum, true, out enumValue);

I wonder what the `true` parameter really represents. In this instance, because I know that method from past experience, I know that this is the ignoreCase parameter.

However, what if this is a totally different method that you’ve never seen before:

service.DoOperation(DateTime.Now, true, false, false, true, currentValue, userName);

This is a particularly sadistic method. But let’s assume that this is the necessary signature of the method. Sadly, it is very unclear what the boolean values do that are being passed in here. What options do we have for adding clarity, assuming we can’t alter the interface?

Firstly, we could pass in some named variables for each of the boolean values:

bool includeHeader = true;
bool checkSecurity = false;
bool validateDate = false;
bool fireCompletionEvent = true;
service.DoOperation(DateTime.Now, includeHeader, checkSecurity, validateDate, fireCompletionEvent, currentValue, userName);

This is already much better, but it is untidily verbose. While we have much more clarity as to what is being passed into the method, it comes with a bit of noise in having to declare the parameters. This feels especially redundant because the variable names will likely be the same as the formal parameter names. As of C# 4.0, we need not do this. Instead, we can use named parameters:

service.DoOperation(DateTime.Now, includeHeader: true, checkSecurity: false, validateDate: false, fireCompletionEvent: false, currentValue, userName);

Sadly, this doesn’t quite work as hoped- the last two parameters are `positional` parameters and cannot appear after named parameters. This means that we must introduce some redundancy:

service.DoOperation(DateTime.Now, includeHeader: true, checkSecurity: false, validateDate: false, fireCompletionEvent: false, currentValue: currentValue, userName: userName);

This is why I would advocate putting boolean values last in the formal parameter list:

service.DoOperation(DateTime.Now, currentValue, userName, includeHeader: true, checkSecurity: false, validateDate: false, fireCompletionEvent: false);

This is much clearer, but it does require you to design your method signatures with this in mind.

Advertisements

8 thoughts on “Put boolean arguments last

  1. I think it is also important to note that once a method argument count grows past 3 to 5, it is likely that the method is doing to much and other design solutions can be employed to simplify the code.

  2. I am sorry but I don’t get this. If you have two boolean values at the end you will come up with the same unreadable signature IMHO.
    What about using the “messaging” approach where a service method is allowed to receive only a specific message contract, which contains all the necessary information? Wouldn’t be that more readable and easier to maintain considering that the message is by nature a contract?

    1. “I am sorry but I don’t get this. If you have two boolean values at the end you will come up with the same unreadable signature IMHO.”

      Did you read the bit about using named parameters?

  3. I agree on that, even naming convention and DSL should be quite verbose too, especially today where we don’t have anymore a physical limit on the size of the variable names. I remember a chapter of “Uncle Bob” book, I guess it was clean code, where he mentioned this concept and explained quite well.
    It makes a lot more sense to write
    totalAmountWithDiscount = totalAmount – totalDiscount
    then reading some crappy code like this
    totAmtDisc = tot – discount

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s