C# defies logic

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


Sad to see C# break basic laws of logic and mathematics like this. ๐Ÿ™  

Thankfully VB doesn’t make this mistake ๐Ÿ™‚

8 Comments so far

  1.   J. Pablo Fernandez on September 6th, 2007          

    What is “int?”?

  2.   Daniel Lyons on September 6th, 2007          

    Interesting observation. ๐Ÿ™‚

    In SQL, the origin of ternary logic, you have some interesting rules involving NULL. Basically, because you don’t know what any given NULL stands for, all NULLs are distinct from each other and not equal.

    Without knowing exactly what’s going on here I’d guess that for portability with C, they’ve decided that NULL == NULL, but retained NULL < NULL and NULL > NULL as unanswerable, as borrowed from SQL.

  3.   bill on September 6th, 2007          

    Hi Daniel,

    C# returns False for nullable < nullable, and nullable > nullable, if either operand is null, unlike TSQL.
    VB on the other hand does null propagation hence if either operand is null, the result is null.
    C# doesn’t do this, it returns a boolean for comparison operators on nullables

  4.   Mitch Wheat on September 7th, 2007          

    I would have expected C# and VB to have been implemented exactly the same:

    NULL (operator) NULL returns NULL

    I suppose the confusion might be contextual:

    i.e a null pointer (ref) can equal a null pointer but a null value never equal a null value.

  5.   MEZIL Matthieu on September 7th, 2007          

    In fact, this append when arg1 and arg2 are null.
    == do null == null so True
    But you can compare inforiority of null and other value. So the result of null <= null is False. In VB, you can't compare two Nullable. So you can't have this. You must test if arg1.HasValue and arg2.HasValue and arg1.Value = arg2.Value. So you can't compare C" and VB for this.

  6.   bill on September 7th, 2007          

    Hi Matthieu,

    VB does have support for operator elevation on nullable types in VB9 (aka VB 2008). The rules are that nulls are alwasy propagated.
    Vb will do an implict widening from Boolean? to Boolean only as part of a Where , an If , or a while expression.

  7.   bill on September 7th, 2007          

    Hi Mitch,

    With C#, the language provides the ability to compare to null, e.g
    if (x == null)
    Now if you replace null, with a variable y and y is null, then agian the laws of transitivity tells us the result should be the same, hence the behaviour of ==.
    The problem is with operators such as <=, where one would expect the result to be the same as the inverse of >. In fact, for intrinsic types C# does compile <= as a > test. Of course that’s a simplification because we do have “undefined” in there as well.

  8.   bill on September 7th, 2007          

    Pablo, int? is the same as nullable in C#, or Nullable(Of Int32) in VB. In Vb9 you can also write Int32?