14

Recently in a previous project I came across a peculiar difference between VB.NET and C#.

Consider the following C# expression which:

null <= 2

This expression evaluates to False which is what I would expect. Then the corresponding VB.NET expression:

Nothing <= 2

I was surprised to learn that this expression actually evaluates to True

It seems like a fairly fundamental design decision between the two languages and it certainly caught me out.

Is anyone able to tell me why? Are null and Nothing one and the same? If so, why do they behave differently?

Gavin Osborn
  • 2,593
  • 3
  • 27
  • 42
  • 4
    `null <= 2` produces a compile-time warning in C# and no IL corresponding to this operation is ever emitted to the output assembly. – Darin Dimitrov Jul 09 '10 at 12:33
  • try an expression in LINQPAD - imagine null is actually an int? who's value happens to be null. – Gavin Osborn Jul 09 '10 at 12:37
  • Related question (though not exactly the same): http://stackoverflow.com/questions/2776902/why-can-you-assign-nothing-to-an-integer-in-vb-net – Hans Olsson Jul 09 '10 at 12:37
  • With all this weirdness going on, sometimes I wonder if we wouldn't be better off with `int i` simply declaring an integer and letting be whatever was already in the memory without trying to give it a default value or do comparisons to `null` as in C++ – Vivian River Jul 09 '10 at 14:30

1 Answers1

30

Nothing in VB evaluates to the default value for a given type. (See this link for details.)

For an integer comparison (which the compiler will assume from the right hand operand), Nothing will thus be 0. 0 <= 2 is true for more obvious reasons :-)

Dan Puzey
  • 33,626
  • 4
  • 73
  • 96
  • 2
    It's also worth mentioning that Nothing is also used for null checks when combined with the Is and IsNot operators. – Justin Niessner Jul 09 '10 at 12:33
  • 2
    For completelyness: what does the compiler with the C# code? `(object)null` does not allow comparison with an integer, `Int32` can't be null ... ? – Stefan Steinegger Jul 09 '10 at 12:36
  • You beat me while I was looking for the answer. And you got the same link, too :P – Wayne Werner Jul 09 '10 at 12:39
  • @Stefan Steinegger: `int` can be implicitly converted to `int?`. See http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx: "The conversion from an ordinary type to a nullable type, is implicit." Therefore the code `null <= 3` will result in the following warning: Comparing with null of type 'int?' always produces 'false'. I assume such code produced a compile time error in C# 2.0. – Dirk Vollmar Jul 09 '10 at 12:48
  • @Wayne: first result from MSDN search - maybe my browser shortcut pipped you to the post ;-) – Dan Puzey Jul 09 '10 at 12:50
  • Sounds like the equivalent to `Nothing` in C# is `default(T)` where `T` is the type. – TMN Jul 09 '10 at 12:58
  • @Stefan/0xA3 - see my edit. I think that's what's going on with the C#. – Dan Puzey Jul 09 '10 at 13:06
  • @Dan Puzey: See Eric's answer here: http://stackoverflow.com/questions/1972262/c-okay-with-comparing-value-types-to-null/1972317#1972317. He is talking about the `==` operator but the same holds for the `<=` operator. It has nothing to do with the `CompareTo` overload. – Dirk Vollmar Jul 09 '10 at 13:22
  • @Dan - yeah, I think it may have been the first result from a google search, too nope, it was 6th. But the first result pointing to an MSDN page – Wayne Werner Jul 09 '10 at 13:58