Boolean parameters considered harmful

A lot has been said on the harm of Boolean parameters. And it seems that this harm is absolute truth without any “it depends”. Recently I had a little accident at my work, which was very much related to Boolean parameter and my own laziness. In C#, I had a class, which I wanted to instantiate. I also wanted that class to be able to act in a little bit different manner, depending on the setting, passed to its constructor. It happened to be 2 different settings possible and I thought, that here was exceptional case and I would better go with Boolean parameter. I made this decision, acted, checked-in. No, I did not unit-test. It was just simple constructor, and simple API to invoke that constructor. It was all great until this Boolean hunted me down few months later.¬† This is what happened. I was instantiating MyClass using Activator.CreateInstance, whose signature was the following:

public static object CreateInstance(Type type, params object[] args)

This is it. Very simple, I just ask to create me an instance of MyClass using its constructor with Boolean parameter. What do you think is the output of the following code?

public static class Program {
    public static void Main() {
        Console.WriteLine(MyClassCreator.CreateWithTrue().MyProperty);
    }
}

public static class MyClassCreator {
    public static MyClass CreateWithTrue() {
        return (MyClass)Activator.CreateInstance(
            typeof(MyClass), 
            true);
    }
    public static MyClass CreateWithFalse() {
        return (MyClass)Activator.CreateInstance(
            typeof(MyClass), 
            false);
    }
}

public class MyClass {
    public bool MyProperty { get; set; }
    public MyClass() { }
    public MyClass(bool myProperty) {
        MyProperty = myProperty;
    }
}

Although I wanted my instance to have MyProperty initialized to “true”, it was actually initialized to “false”. And it was so because of¬†another a bit lazy guy in Microsoft, or whatever company which wrote Activator, who decided to overload CreateInstance in the following way:

public static object CreateInstance(Type type, bool nonPublic)

Now, when compiler performs linking the call to CreateInstance, it choses the overload with closest match and it is the one with Boolean parameter. Hence the wrong method got called and in reality default constructor was used to instantiate MyClass.

Now, of course, you can object and say that one has to look carefully to what he/she invokes. While this is true, it is often really easy to miss something, and therefore it is much better to protect yourself as much as you can. If only I used enumeration with two possible values, this clash would not have happened:

public enum Options { OptionTrue, OptionFalse }

public static class MyClassCreator {
    public static MyClass CreateWithTrue() {
        return (MyClass)Activator.CreateInstance(
            typeof(MyClass),
            Options.OptionTrue);
    }
    public static MyClass CreateWithFalse() {
        return (MyClass)Activator.CreateInstance(
            typeof(MyClass),
            Options.OptionTrue);
    }
}

By the way, this error was not detected on the test, and in fact introduced security issue. And only diligent developer, who wanted to reuse MyClassCreator, stumbled across this strange code with Boolean literals and raised an alarm.

Conclusion: if you want to use a Boolean parameter to whatever method, think twice and be prepared to be hunted down later. Code with Boolean parameters not only makes you think hard to understand what does “true” or “false” might mean in the given context. It also can make you commit very nasty errors.

Facebooktwittergoogle_pluslinkedinmailFacebooktwittergoogle_pluslinkedinmail