Strangely enough considering my background using Visual Basic and programming in Access (since version 1.1 no less, back in the day it was called Access Basic) and developing web sites using ASP when .Net came out I switched straight away to C# and wished never to look back.
However recently I’ve had a choice, rewrite 1000’s of lines of VB 6 code (amounting to over 5MB of pure code), across 10 COM objects manually into C#, or use the Visual Studio 2005 Conversion tool and start using VB.Net. Funnily enough I chose the later.
This has given me my first real world chance to actually use VB.Net, rather than just reading small code snippets on web sites, and I have to say once I got over a few mental hurdles its been a very nice experience.
Problems?
There are quite a few things which are just done in a very different way between C# and VB.Net. Heres a quick list of the main ones that I took a while to find how to do:
- Event Handles – in C# you just use the Object.Event += new Handler(method) etc. In VB.Net there are two methods. You either Dim the item WIthEvents and append “Handles” to the required method or use the AddHandler statement.
Dim WithEvent form As Form
Public Sub Form_OnLoad(ByVal sender As Object, ByVal e As EventArgs) Handles form.Loador
Dim form As New Form
AddHandler form, AddressOf Form_OnLoad - Types and Casting. In C# you can cast by putting brachets before the variable, e.g. int i = (int)shortVariable; Alternatively you can use the Convert.To methods to convert between the value types (e.g. int i = Convert.ToInt32(“123”)). Also there if the typeof method which returns the type of a class (e.g. typeof(Form)).
In VB.Net the Convert.To methods have helpers methods, CStr, CInt, CLng etc, familiar to VB6 users which simply call the relevant Convert.To method. the GetType method is the equivalent of the typeof method.
TryCast is the VB.Net equivalent of the C# “as” operator, with DirectCast and CType methods providing more general casting methods.
- ByVal and ByRef – Even with my experience of these two parameter attributes I was never 100% sure of the difference and always just used ByVal by default. However a lot of my converted code seemed to use ByRef for no apparent reason. A bit of investigation revealed that ByRef is the equivalent of the C# “ref” attribute, except you don’t need to do anything when passing in to a method – I think this is a bad thing personally, its too easy to use ByRef without knowing why.
VB.Net:
Dim i As Integer
Method1(i)
Public Sub Method1(ByRef index As Integer)C#
int i;
Method1(ref i);
void Method1(ref int index) {}I’ve also not managed to find an equivalent to the C# “out” parameter qualifier.
- Different Names for the same thing: “MustInherit” = “abstract”, “Inheritable” = “virtual”, “NotInheritable” = “sealed”, “Shared” = “sealed”
- Modules in VB.Net creating ‘global’ variables and methods. Generally a bad thing which as a coding purist I hate.
- A character in C# uses the single quote marks, e.g. ‘k’. In VB.Net you append the C character to a string, e.g. “K”c – looks ugly as hell that one.
- The auto code comment facility (three single quotes (”’)) is only turned on if generate XML documentation is also turned on – this is bad!
The Conversion Process
The conversion wizard did a very good job considering the size of the code base. The biggest issue by far is the change of arrays going from 0 to n-1 instead of 1 to n. The problem is that some code uses the new indexes and some uses the old.
- The backward compatible “Collection” object uses the old 1 to n, where as all the nice new generics stuff uses 0 to n-1.
- String manipulation functions like Mid, Left and Right use the old 1 to n, where as the String class methods like Substring, Remove etc use 0 to n-1.
e.g. Mid(s, 1, 2) <==> s.Substring(0, 2) - Item collections, such as that of ListBox or ComboBox use the new 0 to n-1.
- The compatability classes of TextBoxArray use the old 1 to n.
On the whole it was all just a big, very laborious nightmare, but the code conversion process does put a UPDATE_WARNING comment/task was added for almost all instances of index use that might/might not need changing.
Also, by default Option Strict is not turned on after the conversion process, in fact its turned Off explicitily in each code file, why it can’t just be set globally I don’t know.
Nice Things
Some nice things about using VB.Net are that the code compiles as you type (or rather when you save or leave a line). So you not only get the syntax highlighting you get in C# but also type checking and every other warning/error you get when compiling.
You also get the “My” namespace which contains instant access to any project resources, e.g. add a string resource call “MyStringResource” and its instantly available (with intellisense) by typing My.Resources.MyStringResource. The addition of the My namespace does add a little bit of size to your project, but once you get beyond a hello world program the difference is negligable.
In the Project Settings you get to use an “application framework” which allows you to specify a spash screen, and set various other things such as enabling Visual XP Styles, Authentication and making it a single instance application, plus automatic saving of Settings (also available via the “My” namespace).
You can set global ‘Imports’ (“using” in C#) which are imported in ever class in a project.
You can refer to other system namespaces without the word “System”, e.g. Dim stream As IO.Stream works as well as Dim stream As System.IO.Stream. I do like this one.
Not So Nice Things
The Visual Basic compiler keeps crashing. There is a hotfix which because I work for a company with Microsoft contacts I’ve got now, but without I think I would have been tearing my hair out by now. Basically about 50% of the time when you stop debugging it would crash Visual Studio.
I’m convinced that the continual compiling mentioned above slows Visual Studio down a bit. Maybe its just the size of my project :(
I’m now very used to Intellisense preselecting the most recently used item in C# – this seems like a wonderful feature now so I miss it in VB.Net
New folders do not create new Namespaces in VB.Net, and I can’t find a switch to make it do this.
If statements run all elements of an If statement if you use “Or” or “And”. e.g. the following would incremement i even if it did equal 1
If i = 1 Or Increment(i) = 1 Then
You need to use OrElse, and AndAlso instead, the following would NOT increment i if i equalled 1:
If i = 1 OrElse Increment(i) = 1 Then
This is particularly relevant if you are doing to usual “If a Is Nothing Or a.Count = 1 Then” which will throw a NullException if a Is Nothing.
There is no inline equivalent to ++ or –. You have to use i += 1 or i -= 1 instead.
There is no satifactory equivalent to the C# “<expression>?true:false”. There are a number of reasons why IIF is not a good choice here. Firstly if you use IIF then both the true and the false part are evaluated, again not good in the case where you can to do the equivalant of (a==null?0:a.Count), in VB.Net IIF(a Is Nothing, 0, a.Count) would throw a NullException as a.Count is evaluated even if a Is Nothing.
Also IIF is a function whose parameters and return type are of Object – therefore you lose all type checking. There is nothing to stop you doing this: Dim f As Form = IIF(boolVal, “A string if true”, -17.5). If you turn Option Strict on it will ask you to cast the return of the IIF to type Form but thats obviously not going to help. The above just doesn’t work in C#, “Form f = (boolVal?”a string”:-176.5);” just wouldn’t compile.
Conclusion
Well, VB.Net is no longer the undiscovered country it once was to me, and I am now quite happily working in both VB.Net and C# at the same time, but I still think my personal preference is going to be C#.
Links
Visual Basic 2005 Expression Edition
Visual C# 2005 Express Edition
Visual Basic ‘My’ Namespace Video
[tags]microsoft, vb.net, c#, visualstudio, programming, coding, comparision[/tags]
Thanks for sharing your experience. At my prior employer, we faced a huge VB upgrade (over 500 VBPs) we had already standardized on C# for new code and we had alot of it. We did not want to deal with learning and supporting VB.NET too.
We were determined to go to C#, and we knew we should leverage our VB6 code as much as possible. Afterall, the VB6 codebase described in detail the layouts and logic for hundreds of forms/controls, it had detailed specs for thousands of DB/service calls, and it had thousands of business logic algorithms. The VB upgrade wizard tool was no help, so we hired a translation tool vendor to build us a custom VB to C# translator.
See the October 2006 .NET developer journal article “Five Pillars of VB Retirement” for the case study.