.NET: bool vs enum as a method parameter

2019-03-27 11:43发布

问题:

Each time I'm writing a method that takes a boolean parameter representing an option, I find myself thinking: "should I replace this by an enum which would make reading the method calls much easier?".

Consider the following with an object that takes a parameter telling whether the implementation should use its thread-safe version or not (I'm not asking here if this way of doing this is good design or not, only the use of the boolean):

public void CreateSomeObject(bool makeThreadSafe);
CreateSomeObject(true);

When the call is next to the declaration the purpose of the parameter seems of course obvious. When it's in some third party library you barely know, it's harder to immediately see what the code does, compared to:

public enum CreationOptions { None, MakeThreadSafe }
public void CreateSomeObject(CreationOptions options);
CreateSomeObject(CreationOptions.MakeThreadSafe);

which describes the intent far better.

Things get worse when there's two boolean parameters representing options. See what happened to ObjectContext.SaveChanges(bool) between Framework 3.5 and 4.0. It has been obsoleted because a second option has been introduced and the whole thing has been converted to an enum.

While it seems obvious to use an enumeration when there's three elements or more, what's your opinion and experiences about using an enum instead a boolean in these specific cases?

回答1:

.NET 4.0 might help here. You can use named parameters:

CreateSomeObject(makeThreadSafe : true);

For older versions it can be useful to create temporary variables instead.

bool makeThreadSafe = true;
CreateSomeObject(makeThreadSafe);


回答2:

I think it would depend on the semantics of your methods, for example does your boolean value actually represent a boolean ? Or is it used just to flag the presence, not presence of another thing?

For example:

// If true, uses 64 bit numbers, if false, 32.
doSomething(boolean)

Even if you know (that at least for the foreseeable future that won't change (unless you want to support 16 or even 8 bits) it would be far more easier to read if you used an enum:

Options.Use32Bit,
Options.Use64Bit.


回答3:

For me it depends on several things:

  1. Readability
  2. The number of Boolean parameters passed in to the method
  3. The chance that I might need more than just true/false

1) Which is more readable?

CreateSomeObject(CreationOptions.MakeThreadSafe);
CreateSomeObject(true);

2) How about now?

CreateSomeObject(CreationOptions.MakeThreadSafe, ExtraGoodies.Include, Logging.Disable);
CreateSomeObject(true, false, false);

3) I might need something more extensible like true/false/indeterminate. If I write it this way from the start then there's no breaking change if I just add an extra item to my enum.



回答4:

You can make use of named parameters in C# 4.0:

CreateSomeObject(makeThreadSafe : true);


回答5:

Clearly the second approach is more readable without an IDE. If you are in VS, you can use intellisense to grok the parameters, although admittedly this can be a bit clumsy at times.

If you are in C# 4.0, you can use named parameters to make your intent clear.