Why Is There a Difference in Checking Null Against a Value in Vb.Net and C#

Why is there a difference in checking null against a value in VB.NET and C#?

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

C# vs VB.NET - Handling of null Structures

If I remember correctly, 'Nothing' in VB means "the default value". For a value type, that's the default value, for a reference type, that would be null. Thus, assigning nothing to a struct, is no problem at all.

What is the difference between NullableT.HasValue or NullableT != null?

The compiler replaces null comparisons with a call to HasValue, so there is no real difference. Just do whichever is more readable/makes more sense to you and your colleagues.

Null(In C#) Vs Nothing(in vb.net)

In your code, VB guesses that you are comparing Strings, since one of the operands is a String. In String comparisons, Nothing is equivalent to the empty String "". It then does a value comparison, which returns True.

Use Is to compare references:

Console.WriteLine(Nothing Is "") '=> False

How does comparison operator works with null int?

According to MSDN - it's down the page in the "Operators" section:

When you perform comparisons with nullable types, if the value of one of the nullable types is null and the other is not, all comparisons evaluate to false except for !=

So both a > b and a < b evaluate to false since a is null...

Null check in VB

Change your Ands to AndAlsos

A standard And will test both expressions. If comp.Container is Nothing, then the second expression will raise a NullReferenceException because you're accessing a property on a null object.

AndAlso will short-circuit the logical evaluation. If comp.Container is Nothing, then the 2nd expression will not be evaluated.

Negating the null conditional operator returns unexpected results for nothing

In VB.NET Nothing is not equal or unequal to anything else(similar to SQL), as opposed to C#. So if you compare a Boolean with a Boolean? which has no value the result will neither be True nor False, instead the comparison will return Nothing too.

In VB.NET nullable without value means an unknown value, so if you compare a known value with an unknown value the result is also unknown, not true or false.

What you could do is to use Nullable.HasValue:

Dim result as Boolean? = l?.Any()
If Not result.HasValue Then
'do something
End If

Related: Why is there a difference in checking null against a value in VB.NET and C#?

Check for null value for value types in VB.NET

KeyValuePair(Of TKey, TValue) is a struct(Structure), it has default value which you can compare to.

Dim dictionary As New Dictionary(Of Integer, string)
Dim keyValuePair = dictionary.FirstOrDefault(Function(item) item.Key = 2)

Dim defaultValue AS KeyValuePair(Of Integer, string) = Nothing

If keyValuePair.Equals(defaultValue) Then
' Not found
Else
' Found
End If

Nothing represents default value of the corresponding type.

But because you are searching Dictionary for a key, you can use TryGetValue instead

Dim dictionary As New Dictionary(Of Integer, string)
Dim value As String

If dictionary.TryGetValue(2, value) Then
' Found
Else
' Not found
End If

.NET DBNull vs Nothing across all variable types?

Normal value types (booleans, ints, longs, float, double, enum and structs) are not nullable.

The default value for all value types is 0.

The CLR won't let you access variables unless they have been set. You may think this isn't always the case, but sometimes the CLR steps in and initializes them for you. At a method level you must explicitly initialize all variables before they are used.

Further, as others point out, since .net 2.0 there is a new generic type called Nullable<T>. There are some compiler shorthands in C# like int? means Nullable<int>, double? means Nullable<double> etc.

You can only wrap Nullable<T> over non-nullable value types, which is fine since references already have the ability to be null.

int? x = null;

For an int?, while you can test against null, it's sometimes nicer to call x.HasValue().

In C# there's also the nullable coalescing operator ?? when you want to assign a nullable to a non-nullable value type. But if you don't have the operator, you can call GetValueOrDefault().

int y = x ?? 2; // y becomes 2 if x is null.
int z = x.GetValueOrDefault(2); // same as y

Why is my Nullable(Of Int32) = 0 after I set it to Nothing?

That's one of the differences between C# and VB.NET. In VB.NET Nothing does not only mean null but also default. So you are assigning the default value of Int32 to the property what is 0. This is caused by the If-operator that has to infer the type from the two values not from the property that you want to assign.

Instead use either an If...Else:

If parentRow.Cells(1).Value Is Nothing Then
dr.ProductStructureHeaderKey = Nothing ' Now it's not 0 but Nothing
Else
dr.ProductStructureHeaderKey = Int32.Parse(parentRow.Cells(1).Value)
End If

or force the nullable with new Nullable(Of Int32):

dr.ProductStructureHeaderKey = If(parentRow.Cells(1).Value Is Nothing, new Nullable(Of Int32), Int32.Parse(parentRow.Cells(1).Value))

Further read: Why is there a difference in checking null against a value in VB.NET and C#?



Related Topics



Leave a reply



Submit