C# defies logic

Posted Fri, Sep 7 2007 2:33 by bill

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 :)

Filed under: , , ,


# re: C# defies logic

Thursday, September 06, 2007 6:35 PM by J. Pablo Fernandez

What is "int?"?

# re: C# defies logic

Thursday, September 06, 2007 11:11 PM by Daniel Lyons

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.

# re: C# defies logic

Thursday, September 06, 2007 11:48 PM by bill

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

# re: C# defies logic

Friday, September 07, 2007 1:44 AM by Mitch Wheat

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.

# re: C# defies logic

Friday, September 07, 2007 4:22 AM by MEZIL Matthieu

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.

# re: C# defies logic

Friday, September 07, 2007 5:13 AM by bill

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 <condtition> , an If <condition> , or a while <condition> expression.

# re: C# defies logic

Friday, September 07, 2007 5:21 AM by bill

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.

# re: C# defies logic

Friday, September 07, 2007 5:22 AM by bill

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