The Collapse of Boolean Logic

0 comments suggest edit

What will this code write to the console?

public void SomeMethod()

{

    SqlInt32 x = 1;

 

    if(x == SqlInt32.Null)

    {

        Console.WriteLine(“Null.”);

    }

    else if(x != SqlInt32.Null)

    {

        Console.WriteLine(“Not Null.”);

    }

    else

    {

        Console.WriteLine(“Neither? WTF!?”);

    }

}

If you said “Neither? WTF!?” then you’d be correct.

Doesn’t that seem odd since x is either SqlInt32.Null or it isn’t? Is this a case of fuzzy logic? Well not exactly. This is one of those gotchas with operator overloading. The == operator is overloaded by SqlInt32 to return a SqlBoolean instead of a boolean.

This caused me a few minutes of pain this week as I was stepping through code like this and examining the values in the debugger and I thought perhaps someone had slipped me a very strong hallucinogen because there I was with a value that was not null, but was null at the same time. It was one of those mind warping “This sentence is not true” moments.

As typical, I was thinking about rebooting when on a whim I decided to use intermediate variables and realized that the == was returning something neither true nor false. Honestly, I think this is a very poor and unnecessary use of operator overloading (correct me if I’m wrong) because it hides a real gotcha underneath a very common paradigm. If you overload the == operator, you should most definitely return a bool.

In this case, it’s easy enough to fix. I should have been checking the IsNull property anyways like so:

public void SomeMethod()

{

    SqlInt32 x = 1;

 

    if(x.IsNull)

    {

        Console.WriteLine(“Null.”);

    }

    else

    {

        Console.WriteLine(“Not Null.”);

    }

}

This post by Cyrus motivated me to write about this.

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

3 responses

  1. Avatar for Ayende@ayende.com (Ayende Rahi
    Ayende@ayende.com (Ayende Rahi April 15th, 2005

    How do you enable intermediate variables display?

  2. Avatar for Haacked
    Haacked April 15th, 2005

    What I meant was I changed the code slightly to use an intermediate variable. For example,



    bool y == (x == SqlInt.Null);



    That didn't compile so I tried:



    object y == (x == SqlInt.Null);



    Then in the debugger I checked the type of y. Sure enough, it was SqlBoolean.

  3. Avatar for Bender
    Bender April 18th, 2005

    You should never use a 'Null' in Boolean Logic, use IsNull. The SqlInt32.Null should be used as a Type specifier not a value.