To fully understand VB Gotcha #1 we need to look at the brief history of Visual Studio.NET and spend some time understanding .NET arrays and VB.NET implementation of arrays.
Consistent model
With the release of VB 7.0 (VB.NET) there was a lot of hoopla from Microsoft concerning the more consistent programming model. One of the new consistency rules was:
Thou shall always use parenthesis when calling methods.
This was good. In prior versions of VB there was some glaring inconsistencies. For instance if you called a sub procedure the parameters were not to be placed in parenthesis. On the other hand when calling a function the parameters were required to be in parenthesis. There were other exceptions to these rules but I don’t want to dwell on them here. Needless to say when I was teaching a class with programmers who were new to VB this was one of those head scratching, puzzled look moments that all VB instructors encounter from time to time.
Visual Studio Intellisense
Visual Studio and VB.NET are not the same thing. This is obvious to most developers but I mention it here because the VS.NET IDE sometimes exacerbates the situation .In this story, Visual Studio.NET intellisense was very helpful in adding parens to your code. If you typed…
Messagebox.Show "abc"
Visual Studio would fix it up for you…
Messagebox.Show ("abc")
This is easy for the VS team to accomplish. Look for method calls; determine if I have placed parenthesis around the arguments; if not add the parens.
VS 2002 Constructors
Since VB.NET was now fully OOP it supported constructors for instantiating classes. VS 2002 in the guise of being helpful would add parens to new object instantiations.
152 Dim H1 As Hashtable
153 Dim H2 As New Hashtable ( ) ‘ note parens added by VS
154
155 Dim H3 As New Hashtable(100) ‘ arguments are enclosed
156
The reason for this behavior? In line 153 we are calling the class constructor - which is considered to be a method. Thus VS.NET 200 intellisense does what is supposed to - add parens.
Arrays
We will now take a side trip to look at arrays. Check out the following code.
1 Dim trees( ) As String ‘ creates an array
2 Dim flowers As String( ) ‘ creates an array
Note that there are two syntaxes for declaring an array. Line 2 is the odd ball. If you place parenthesis after the datatype you will wind up creating an array. To me this is just plain stupid. There really is no need to have the second syntax - though there might be a valid reason why the compiler allows code like this to exist. It is confusing and it leads us to our next part of the gotcha.
Instantiating an object
Remember that VS.NET adds parens when instantiating an object.
1 Dim shrubs As New Hashtable( ) ' note the parens added by VS.NET 2002 2 3 ' developer decides to instantiate on second line 4 ' or New keyword is not allowed because the class has a private constructor 5 6 shrubs = New Hashtable( )
Now the troubles start. You go back and remove the New keyword from line 1.
1 2 Dim shrubs As Hashtable( ) ' the parens are still there unless you remember to remove them. 3 ' the compiler doesn't care - it thinks you are creating an array now. 4 5 6 7 shrubs = New Hashtable( ) ' compiler error on this line
You will get a compiler error.
Value of type ‘System.Collections.Hashtable’ cannot be converted to ‘1-dimensional array of System.Collections.Hashtable’.
Why? Because the compiler thinks that you are declaring a one dimensional array!
After you have seen this error a few dozen times you will know what you have done and will immediately find and delete the extra parenthesis. Soon you learn that if you remove the New keyword you always need to delete the remaining parenthesis. Unfortunately VS.NET 2002 will add the parens but not remove them in the scenario.
Visual Basic .NET 2003
I was teaching a class shortly after VB.NET 2003 was released. One of my students called me over to look as some code that he had written for an exercise.
Dim shrubs As New Hashtable
There was no parenthesis after the constructor. The student dutifully typed in the parens - like the sample code in the book - and Visual Studio removed them. So I tried this code.
1 Dim trees As Hashtable 2 trees = New Hashtable
Nope. Visual Studio removes the parens from this constructor call too. Huh? Apparently VS 2003 has some new intellisense. I spent some more time investigating including talking to a friend on the VB compiler team. The theory [not concretely proven yet] is that Visual Studio.NET was changed to remove parenthesis from constructors that have no parameters to counter the VS 2002 behavior explained above.
I tested this behavior with the VB command line compiler (VBC.EXE) and it is not an issue.
So what is Gotcha #1?
If you are writing code in Visual Studio.NET 2003:
You must use parenthesis for all method calls - irregardless whether the method is written as a sub procedure or a function - UNLESS you are calling a constructor with NO parameters.
Comments
# re: VB Gotcha #1 - The case of the disappearing parenthesis 7/22/2004 4:42 PM Paul Vick
Your theorizing is correct. In VB 2005, if you put the parenthesis there, however, we will honor them and not remove them.