Search code examples
vb.netdefault-value

VB Nullables and Nothings


I researched C#'s default keyword equivalence in VB.NET and came across this question.

Then I got curious. Some background - I'm working with parsing an excel spreadsheet, where many columns can be null, and there is certainly a difference for me between an integer column being 0 and being null.

I wrote a little parse method:

Function Test(ByVal i As String) As Nullable(Of Integer)
    Dim j As Integer

    If Integer.TryParse(i, j) Then
        Return j
    Else
        Return Nothing
    End If
End Function

this seems to work correctly. But here, I can return an Integer if i want:

Function Test(ByVal i As String) As Nullable(Of Integer)
    Return 2 'or Return Nothing
End Function

which I can in C# as well:

 static void Main(string[] args)
 {
     int? j = Test("1");
 }

 public static int? Test(string i)
 {
     return 2; //or return null
 }

In the code above, if I change j to an int, I'll get a compile-time conversion error, which makes total sense.

Now my question - in VB, if i attempt a similar approach:

Sub Main()
    Dim j As Integer = Test("hello")
End Sub

Function Test(ByVal i As String) As Nullable(Of Integer)
    Dim j As Integer
    Return If(Integer.TryParse(i, j), j, Nothing)
End Function

or, in my test case where i is not an Integer it can be rewritten as:

Function Test(ByVal i As String) As Nullable(Of Integer)
    Return DirectCast(Nothing, Integer)
End Function

because of the way Nothing works in VB.NET, this code compiles and runs without error -- j is set to Integer's default 0.

This feels so dirty to me. In this scenario you can somewhat alter the method's intentions without any warnings or errors. I'm just curious I suppose, is this an unintentional by-product of the way Nothing works in VB, or is this the intended purpose?


Solution

  • Your VB.Net code compiles because you're using late binding, which allows changing the type of a variable at runtime.

    If you compile your code with OPTION STRICT ON, you'll get a compiler error like:

    Option Strict On disallows implicit conversions from 'Integer?' to 'Integer'.