Why don’t relational operators return bool as a type?

Section 10.9.2 of the language specification says:

A binary operator must take two parameters, at least one of which must have the class or struct type in which the operator is declared. Parameters of the shift operators (§7.8) are further constrained. A binary operator can return any type.

Why isn’t it limited to just returning bool?

There is some weirdness here because of the C# ability to support nullable types, such as the SQL types (ie SQLInt32, SQLSingle, etc.). These type can either have a value or be null.

One of the strange features of the SQL expression syntax is if either operand in a binary operation is null, the result is null. So, when we want to write the comparison operator for SQLInt32, we have a problem if the result type is constrained to bool, since null is neither true or false.

C# therefore allows the comparison operators to return another type as long as the resulting type has operator true and operator false defined. That gives us enough support to be able to write:

SQLInt32 x = …;

SQLInt32 y = …;

if (x == y)


    // x and y or equal


else if (x != y)


    // x and y are not equal




    // the result of the comparison is null



Which allows the full richness of SQL types to be expressed.

Author: Eric Gunnerson]