Why don’t nullable relational operators return bool? instead of bool?

Q: Why don’t nullable relational operators return “bool?” instead of “bool“?

Nullable types are a new feature of C# 2.0.

When dealing with nullable types, if you write the following:

int? i = 15;
int? j = 16;

the type of

i == j

is a normal bool, rather than a bool? (ie nullable bool). Why?

A: In our initial designs, we spent a fair amount of time discussing what the behavior should be here, and how we should cross over from the three-valued nullable world to the two-valued “normal C#“ world.

Consider the following method:

void Process(int? p)
{
    if (p == null)
    {
        // do some processing…
    }
}

This seems like a very natural thing for a C# user to want to write. But if equality is three-valued, comparing anything to null always returns a null value (ie null isn’t equal to anything), and therefore such a comparison can never succeed. Instead, the user would have to write:

if (!p.HasValue)

or something similar. We decided that the value of having a model that was consistent with the way users were used to dealing with reference null was pretty high, and therefore decided to make the relational operators return bool.