Nullable<bool> usage guideline

I am starting to work on some updates to the framework design guidelines related to new framework and language features added in .NET 2.0, 3.0, and 3.5. One of such additions are the nullable types (Nullable<T>).

Coincidentally, somebody asked me today whether they should use Nullable<bool>. Here is the question:

Q: Do the guidelines have anything to say about the use of nullable types in public API? Subject came up here in context of a proposal to return Nullable<bool> from a method to retrieve an attribute value (null means attribute not found, true means value retrieved, false means no value for existing attribute).

… and in the absence of formal guidelines, here is what I recommended:

A: I would say that the rule of thumb is that you should use Nullable<bool>, if it’s obvious what all three values mean. For example, it there is an optional column in a database of type Boolean, it’s clear that true means true, false means false, and null means the value is not there. In your example, you had to explain what the values mean, so I would not recommend using nullable types.

Comments (6)

  1. joshwil says:

    The example given seems like a perfect excuse to return an enum.

  2. JoshCh says:

    How about getting ADO.NET to properly support nullable types?  It would save a ton of a code to be able to have the DBNull.Value handled as a normal null in the following case:

    long? id = (long?)dataReader["id"];

    If dataReader["id"] is DBNull, id gets set to null.  This way nullables become much more useful.

  3. Michael Neel says:

    No, no and no.  No.


    Oracle does this – conditions can return true, false, or null (if a value in the expression was null).  This is one of those things that lead to weird bugs you don’t expect – and isn’t often thought of in the first round of unit tests.

    If you have a third meaning, make an Enum so it’s clear what the three states mean.  

  4. Thanuja says:

    Well in the attribute example i think if the attribute is not found you should return and exception as it is an impt info for the upper layers(if layered patterned is used)

  5. Andrei Rinea says:


    Regarding :

    long? id = (long?)dataReader["id"];

    are you sure if dataReader["id"] is going to be DBNull.Value (the sole instance of the DBNull class) then it will be castable to "long?"? As far as I know that will throw an InvalidCastException.