A non-Obvious Benefit of Replacing Boolean Arguments with Enumerations

When a method takes a boolean argument, it is sometimes better to restructure the method so that it takes an enumeration argument. In this article we show that the real benefit of this is not obvious and is often misunderstood.

Consider the following method and one of its clients:

void search(bool useCaseSensitiveSearch)
  { ... }

void client()
{
  ...
  search(true);
}

It’s usual to notice that rewriting to use an enumeration argument clarifies the caller’s intent:

enum SearchCaseStyle
  { CaseSensitive, CaseInsensitive }

void newSearch(SearchCaseStyle caseStyle)
  { ... }

void client()
{
  ...
  newSearch(SearchCaseStyle.CaseSensitive);
}

Sure enough, changing the argument from boolean to enumeration has clarified the intent of the caller - a positive outcome. But there are other ways to clarify the caller’s intent. One way is to follow the popular guideline of avoiding passing literals as parameters:

void client()
{
  bool caseSensitiveSearch = true;
  oldSearch(caseSensitiveStyle);
}

Another way to clarify the caller’s intent is to use comments.

We’ve seen that using an enumeration argument clarifies client intent, but that client intent can be clarified using other techniques, too. What, then, if anything, is the advantage of using an enumeration argument? It is as follows.

Rewriting a method to use an enumeration argument instead of a boolean argument increases the probability that a given caller’s intent matches the mechanism that the caller uses to communicate the intent.

This safety is something the other techniques for clarifying caller intent cannot provide. With a boolean argument, for example, even if the caller defines a constant to clarify intent, a mistake is still easy to make:

void client()
{
  bool isCaseInsensitiveSearch = true; // should be false
  oldSearch(isCaseInsensitiveSearch);
}

Here there is a mismatch between the way the caller defined the literal and the semantics of the called method. When a boolean argument is converted to an enumeration argument, such mismatches become much less likely. This is the real benefit of using an enumeration for an argument instead of a boolean value. The added safety is due to the creation of a new type; this allows the compiler to do static type checking on arguments passed in by callers.

The general principle is:

Creating a well thought out enumeration or other type for a particular method argument can make it more likely that a given value passed in by a client will match the client’s intent.

As a bonus, the client’s intent is documented almost automatically by virtue of reference to the type in client code, e.g., SearchCaseStyle.CaseSensitive.