VB.NET and Block-Scoped Variables
When I was first introduced to .NET, I learned C#. I came from a C++ and Java background, and so C# seemed like the most natural language for me to choose for development. My entire development team worked in C#, and everything was beautiful.
Then, my company won a contract to perform a major system rewrite and integration project, and the developers that we are working with here came from VB. So naturally, we chose to use VB.NET for this integration. I've been coding in VB.NET for about two years now, and I've actually come to like it somewhat. Optional parameters are nice (if you just use VB), instead of needing to create a bunch of single-line overloads. But, I've been smacked back into reality. Check out the following two code snippets, one in C# and one in VB.
[C#]
for (int i = 1; i < 10; i++)
{
object o;
// Any variable condition will work here.
if (i % 2 == 0)
o = new object();
if (o == null)
o = "
MessageBox.Show(String.Format("Loop execution {0}: o is {1}", i, o.ToString()));
}
[VB.NET]
For i As Integer = 1 To 10
Dim o As Object
' Any variable condition will work here.
If (i Mod 2 = 0) Then
o = New Object
End If
If o Is Nothing Then
o = "
End If
MessageBox.Show(String.Format("Loop execution {0}: o is {1}", i, o.ToString()))
Next i
The C# version of this code doesn't even compile. It complains, "Use of unassigned local variable 'o'", which is correct. The VB version, on the other hand, not only compiles, but IT NEVER SETS o TO NULL!!! That's just pure evil if you ask me. After doing some reading, I found that VB.NET doesn't support block-scoped variables. When you declare a local variable just inside a block, it's exactly the same as declaring it just outside a block. Developers *of* VB.NET should at least warn you that your variable is scoped at the procedure level, not at the block level. Developers *using* VB.NET should always, always, always initialize their variables to null values, to avoid errors that can rise from this wickedness.


3 comments:
This is absolutely incorrect. o is only created once, even though it is inside a loop. Keep in mind you are using garbage collection for memory management, not deterministic finalization like C++. At the first pass of the loop, o is nothing and the empty string is output. o is initialized during the second pass, and the ‘is nothing’ branch will never execute again during the loop, because o is not destroyed or reclaimed by the garbage collector.
Local variables: scope vs. lifetime (plus closures)
Fair enough, I concede that o is scoped inside the loop, so VB does support block-scoped variables. However, I believe my point is still valid: that VB shouldn't distinguish between scope and lifetime, and that it should re-initialize the block-scoped variable on each loop execution, or force you to do so like C# does.
Post a Comment