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.