Aug 29, 2008

Equating Nullable Types : strange ways

C# has some interesting rules for operators on nullable types. Given:
int? x ; int? y ;
Laws of transitivity tells us that if x is equal to y, (x == y), then x<= y would be true too. Well not in C#. With this function:
static void test(int? arg1, int? arg2)

{
Console.WriteLine("arg1 == arg2 returns {0}", (arg1 == arg2));
Console.WriteLine("arg1 <= arg2 returns {0}", (arg1 <= arg2));
}

The output in some cases will be:
arg1 == arg2 returns True

arg1 <= arg2 returns False



A comparison operator (==, !=, <, >, <=, >=) has a lifted form when the operand types are both non-nullable value types and the result type is bool. The lifted form of a comparison operator is formed by adding a ? modifier to each operand type (but not to the result type). Lifted forms of the == and != operators consider two null values equal, and a null value unequal to a non-null value. Lifted forms of the <, >, <=, and >= operators return false if one or both operands are null.


When one of the operands of the == or != operator is the null literal, the other operand may be of any nullable type regardless of whether the underlying value type actually declares that operator. In cases where no operator == or != implementation is available, a check of the operand’s HasValue property is substituted. The effect of this rule is that statements such as
if (x == null) Console.WriteLine("x is null");

if (x != null) Console.WriteLine("x is non-null");

are permitted for an x of any nullable type or reference type, thus providing a common way of performing null checks for all types that can be null.