Migrating VB.NET to C#: it's a non-trivial problem
by John Browne, on Jul 27, 2020 5:15:41 PM
VB.NET: we have to talk.
Remember how great it was when we first met VB.NET? I couldn't stop thinking about you, how easy it was to write a Windows app (goodbye HWNDs!), rapid UI prototyping, DATABASE CONTROLS? I mean, come on: it was love at first sight.
We grew up together. You went from young sexy VB classic to a more stolid VB.NET--yeah, you put on some weight but I still loved you. All these years, I've never cheated on you. Not once.
Look, it's not about you, ok?
I've, well, changed.
I used to think Windows Forms apps would make me happy forever. I thought that the .NET Framework was the most beautiful thing I had ever seen.
Until I saw .NET Core.
So sleek. So lean. So enticingly portable. And I fell in love all over again.
Just not with you. My bad.
.NET Core & C# are the future; VB.NET is the past
I didn't come here to bash VB.NET; it's a terrific programming language that helped a lot of people make the jump from VB6 to .NET. And it brings out loyalty to a degree that makes deadheads look non-committal.
Microsoft has made it clear that .NET Core is the future and VB.NET is not going along for the ride. To get 100% into .NET Core, you need to convert VB.NET to C#. If desktop apps are enough for you and your users, VB.NET works with NET 5, but only to target Windows Forms--not WPF. But if you want to write web apps running on ASP.NET Core, you'll need C#.
This doesn't mean your VB.NET apps will stop running on Windows--Microsoft has made it clear they will continue to support .NET Framework, but they're not going to invest in the Framework much (if any) and no more improvements to VB.NET will be forthcoming.
Aside from the details of which programming language and which .NET classes are available, the implications of this move by Microsoft are substantial. With .NET Core, you can write C# apps that run on Linux. You can write Windows web apps that run in a Docker container, and you can host the container on a Linux server. You can write command shell apps that run almost anywhere. Since Core is open-source, the sky's the limit as to where it can or will run. How about Raspberry Pi? Yep, .NET Core 3.1 (LTS) can run there.
There are more differences than you might think
Are C# and VB.NET the same? For years I've heard developers say, "Oh, VB.NET is just C# with VB syntax. They're basically the same." Those same developers probably think that a little time with regex is all they need to convert their VB.NET source code into good C# code.
Turns out that's not exactly true. You have to look past the syntactic differences, which seem relatively easy to sort out. It's not that hard to find
Dim x as Integer
and convert it to
and work through some basics like that. Or to take a slightly more complex example, in VB.NET parentheses are optional on Sub or Func when no parameter is being passed; in C# you have to convert those to use empty parentheses, so myObject.ToString gets converted to myObject.ToString(). Again, not too hard with regex.
You can even save yourself the headache of trying to sort out regex expressions and use one of the many language conversion options you can find with a simple Google search. But taking that approach ignores the real, significant semantic differences between the two languages.
That link (which goes to one of the principle Microsoft developers who implemented VB.NET) was our starting point to figure out how to write tooling to convert VB.NET to C# using semantic analysis. My mate Mauricio Rojas will be blogging about some of these problems and how we addressed them in future posts. For now, here are a couple to whet your appetite.
VB.NET properties with parameters
VB allows for parameterized properties (which doesn't seem like a particularly good idea) but C# doesn't. So we convert those properties by creating getters and setters in the form of get_Property() and set_Property(parameters).
For and For Each loops are different
VB.NET has some unusual features in control loop iteration. For example, if an iteration variable has already been declared and is still in scope, it can be reused. Plus, iteration variables can be reassigned inside the body of a loop. The general solution is to declare a temporary variable and reassign it to the previously declared variable. For example:
would be migrated to:
Well, that's enough for now. We have some super-smart folks working on this in a way that allows for accurate semantic conversion of VB.NET to C#--targeting either .NET Framework or .NET Core--such that the app won't be broken. By that I mean that the actual way the code functions is preserved as much as possible. You just can't get that with a simple syntactic converter.
So if you're ready to break up with your first love, give us a shout and we'll show you how easy it is to cuddle up with .NET Core and C#.
Edit: since publishing this blog post a couple of readers have let me know that the image used at the top might be disrespectful. I appreciate the feedback and am glad to live in a time when people will voice their opinions when they see things they believe should be corrected. The image is a wildly popular meme that even has its own wikipedia page. When I write these posts, I aim for some balance between useful, relevant, and entertaining. Sometimes the balance tips a little more one way or the other. If anyone is offended by this or anything else published here, I sincerely apologize.