Reputation: 3715
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 ?
Upvotes: 0
Views: 892
Reputation: 74660
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.
Upvotes: 3
Reputation: 54457
There are three options in VB that are relevant here and you should understand what each does.
Option Explicit
is actually the one that can allow implicit declarations. It is On
by default and should NEVER be turned Off
. When Off
, you can introduce a variable in your code without prior declaration. When On
you MUST declare every variable before use.
Option Infer
is fairly new and was introduced with LINQ to support anonymous types. When Off
, all variables must have their data types specified explicitly or, where it is allowed, they will default to type Object
. When On
, the type of a variable can be specified implicitly by initialising the variable where it is declared. Whatever the return type of that expression will be type inferred for the variable. It is On
by default and should probably be left that way but it can be turned Off
if you won't be using anonymous types and don't mind explicitly specifying the type of every variable. Type inference is not supported for member variables.
Option Strict
is a big bone of contention. It is Off
by default, mainly to facilitate upgrade of VB6 code but also to make the language more forgiving for beginners. You should turn it On
in the properties of any existing projects and also in the IDE options so that it will be On
by default for all future projects. When Off
, you are permitted to omit any data type specification for any variable, property or method and they will default to Object
unless type inference is possible. You are also permitted to rely on implicit conversions when setting variables or properties or passing method arguments. Late binding is also permitted, i.e. accessing members that the compiler cannot confirm exist and must be confirmed at run time. That is all bad in almost every situation. Option Strict
should be On
by default so you are forced to always specify and use the correct data type. In the very rare situations where late binding is required, you can turn if Off
at the file level in the minimum of files containing the minimum of code that actually requires it.
In your particular case, the issue is that you have Option Strict Off
and so your variable is type Object
. That regardless of Option Infer
because type inference is not supported for fields. The compiler doesn't know what members the object it refers to will have so it lets you do anything. You try to access a member that doesn't but that is determined until run time.
Turn Option Strict On
, specify the type of that field and then only use members in your code that that type actually has, which will be enforced by the compiler instead of being deferred until run time.
Upvotes: 0
Reputation: 1185
I know this will not answer the question of 'implicit variable', but may help to solve the problem of OP.
As the comments say, there is no such Method in .net for the type SortedDictionary(Of TKey, TValue)
You will need to test the 'Count' Property - it will throw Exception if your object is Nothing (null in C#)
Or you could use one of the LINQ-Functions of .net
e.g.
import Linq (make sure System.Linq.dll
is referenced)
Imports System.Linq
and test your Dictionary
If Not oEnvironMap.Any() Then
'is empty
end if
Upvotes: -1