In VB.NET this happens:
Dim x As System.Nullable(Of Decimal) = Nothing Dim y As System.Nullable(Of Decimal) = Nothing y = 5 If x <> y Then Console.WriteLine("true") Else Console.WriteLine("false") '' <-- I got this. Why? End If
But in C# this happens:
decimal? x = default(decimal?); decimal? y = default(decimal?); y = 5; if (x != y) { Debug.WriteLine("true"); // <-- I got this -- I'm with you, C# :) } else { Debug.WriteLine("false"); }
Why is there a difference?
VB.NET uses the keyword Nothing for null values. When defining a string in a class, dont initialize it to null. Instead, initialize it to the constant String. Empty.
When checking whether a reference (or nullable value type) variable is null , do not use = Nothing or <> Nothing . Always use Is Nothing or IsNot Nothing . For strings in Visual Basic, the empty string equals Nothing .
The System. DBNull value indicates that the Object represents missing or nonexistent data. DBNull is not the same as Nothing, which indicates that a variable has not yet been initialized. DBNull is also not the same as a zero-length string (""), which is sometimes referred to as a null string.
With references, it means a reference that points to no object. And with values, it means the default (zero-initialized) value. On references, Nothing is null. It may provoke a NullReferenceException. As VB.NET developers, we must understand that "null" refers to Nothing.
VB.NET and C#.NET are different languages, built by different teams who have made different assumptions about usage; in this case the semantics of a NULL comparison.
My personal preference is for the VB.NET semantics, which in essence gives NULL the semantics "I don't know yet". Then the comparison of 5 to "I don't know yet". is naturally "I don't know yet"; ie NULL. This has the additional advantage of mirroring the behaviour of NULL in (most if not all) SQL databases. This is also a more standard (than C#'s) interpretation of three-valued logic, as explained here.
The C# team made different assumptions about what NULL means, resulting in the behaviour difference you show. Eric Lippert wrote a blog about the meaning of NULL in C#. Per Eric Lippert: "I also wrote about the semantics of nulls in VB / VBScript and JScript here and here".
In any environment in which NULL values are possible, it is imprtant to recognize that the Law of the Excluded Middle (ie that A or ~A is tautologically true) no longer can be relied on.
Update:
A bool
(as opposed to a bool?
) can only take the values TRUE and FALSE. However a language implementation of NULL must decide on how NULL propagates through expressions. In VB the expressions 5=null
and 5<>null
BOTH return false. In C#, of the comparable expressions 5==null
and 5!=null
only the second first [updated 2014-03-02 - PG] returns false. However, in ANY environment that supports null, it is incumbent on the programmer to know the truth tables and null-propagation used by that language.
Update
Eric Lippert's blog articles (mentioned in his comments below) on semantics are now at:
Sep. 30, 2003 - A Whole Lot of Nothing
Oct. 1, 2003 - A Little More on Nothing
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With