Search code examples
vb.netvariable-declaration

In VB.NET, is IMPLICIT variable declaration (= New) allowed for all types of variable?


I translated a Java program to VB.net. The program has been built without error.

When I execute the program for first time, the program crashes on following line

If oEnvironMap.isEmpty() Then

indicating that

System.MissingMemberException : public member 'isEmpty' from 'SortedDictionary(Of String,String)' type is not foundable

where oEnvironMap declaration line is following

Private oEnvironMap = New SortedDictionary(Of String, String)

If I add as word as in following code

Private oEnvironMap as SortedDictionary(Of String, String) = New SortedDictionary(Of String, String)

building application return a lot of errors on methods used with oEnvironMap.

Personnally, I thought that declaring a VB.Net variable using implicit declaration is allowed.

I now see that is not working for complex array as Dictionary !

Is that a bug in Visual Studio Community 2019 that I can communicate to MSDN or it is simply a personal misunderstanding ?


Solution

  • Here are various ways you can make a variable in VB. I'll pick on something basic such as making a new string out of a single char c so on the right hand side we always have "a string"

    Private s = New String("c"c, 1) 's is Object, compilation fails if Option Strict On even if Option Infer On
    Private t As New String("c"c, 1) 't is String, shorthand of below
    Private u As String = New String("c"c, 1) 'u is String
    
    Private Sub Blah()
    
        Dim x = New String("c"c, 1) 'x is Object if Option Infer Off, and fails to compile with Option Strict On but succeeds if Off. x is String if Option Infer On and compilation succeeds regardless of Option Strict
        Dim y As New String("c"c, 1) 'y is String, shorthand of below
        Dim z As String = New String("c"c, 1) 
    
    End Sub
    

    It's perhaps important to draw a distinction between the Private member variable s and the local Dim'd variable x.

    With Option Strict Off and Infer Off, all these will compile, but s and x will be Object, intellisense will only show you Object members. VB will figure things out at runtime and treat them as strings but you get an error if you try to use things that aren't available on String (it's still a string, just "looks like Object")

    With Option Strict On and Infer Off, s and x will fail to compile, and you need to use "As" somewhere to get them typed as a string. Intellisense will then work because the compiler resolves the variables to strings because they've been As'd

    With Option Infer On, you can get away with writing Dim x = ... because the infer will look at the right hand side and see it's a string, and type x as string for you, but it's only true for Dim'd local variables, not class member variables. This means that having Strict On and Infer On you still get a compiler error but this time only on the Private s because it hasn't been As'd and Infer didn't As it for you


    And all this is unrelated to generic types - anything that mentions X(Of...) - you can swap out the New String("c"c, 1) for New Dictionary(Of String, Int) and experience all the same rules


    The behavior of your vs is thus:

    Private oEnvironMap = New SortedDictionary(Of String, String)
    

    Strict is off, Infer is irrelevant, oEnvironMap is an Object and no compiler errors will occur because VB puts it down as "gotta figure that one out at runtime". At runtime, turns out isEmpty ain't a thing -> exception

    If you give it a type with either:

    Private oEnvironMap As New SortedDictionary(Of String, String)
    Private oEnvironMap As SortedDictionary(Of String, String) = New SortedDictionary(Of String, String)
    

    Suddenly the compiler knows it's a dictionary, and starts figuring out all the errors (that would have happened at runtime before) now at compile time instead. It can now tell you "isEmpty ain't a thing" as part of the compilation. Every single one of those error in the output window is something that would have caused an exception at runtime with the earlier form. This isn't a "OMG I added one thing and suddenly a hundred errors appeared - that must have been the wrong thing to do"; the errors were always waiting to happen

    Turning Option Strict On would have simply enforced that you did either of these latter two.