Skip to content
Graham edited this page Feb 20, 2024 · 28 revisions

This converter creates code as close as possible to what the old code did. Even sane code can look messy when it's been converted, whereas hacky legacy code can look atrocious. You'll want to do a bunch of automated cleanups after conversion.

High level advice

  • Spike it. Something doesn't compile? Replace the method body with return null. Find out how many of those are needed to make it work for a start.
  • Commit every single thing you do - clear up after if needed
  • Expect to run the converter multiple times
  • For any project, but especially legacy projects with low/no tests, before you convert, add a bunch of extra characterization tests using something like Verify to keep track of what a bunch of outputs look like and spot subtle changes in behaviour.

Process of converting

Before performing any conversion, it's recommended to:

  • Ensure you have no uncommitted changes in your version control system. This will make it easy to see the result of the conversion, and discard any parts you don't want.
  • Create a new branch
  • Ensure your solution compiles (for maximum conversion accuracy).
  • Split out any files over about 5000 lines (using partial classes if needed). Converting two 5000 line files is usually significantly faster than converting one 10000 line file. This may be slightly less of an issue with the command line.
  • Immediately after conversion, commit the result, this will make it easy to report issues
    • I'd always recommend separating automated from manual steps in commits initially - it makes it so much easier to make use of the history to locate/correct mistakes, after all, what else is the history for?
    • Converting a project to a totally different language is inherently somewhat messy and has a whole bunch of steps. Trying to pretend it all happened in one go will just make life harder 3 months down the line when you notice an issue and can't figure out at which point in the process it got introduced.
    • If being on a branch isn't enough, and for whatever reasons you need to sweep the mess under the rug later, in git it's pretty straightforward using rebase (there's even an option in GitHub to squash rebase a branch).

The first goal is to get the output compiling and commit it. Then to get the tests passing (and commit it), then to improve the code quality and simplify overly cautious converted code (e.g. extra null checks that you know aren't needed).

Advanced git usage tip: so that it's easily visible in git history if needed, you can actually do a commit where you rename the .vb files to .cs extension beforehand. I.e. Do a recursive rename, commit, reset hard to previous commit, reset soft to rename commit, convert, delete vb files, commit.

Code style

I'd recommend setting up a .editorconfig and using: dotnet-format to format things the way you like.

JetBrains' ReSharper (which has a free trial) contains a structural find/replace that can be very useful for replacing one pattern with another. Otherwise Regex may be sufficient.

VB - C#

Consider turning Option Strict On and fixing any issues before conversion:

  • VB treats fields with an unspecified type as Object and generates all sorts of code behind the scenes to try to deal with that. If you know what type you need I'd recommend specifying it before conversion to improve the output. There are various automated fixup extensions which may help with this and other code improvements before/after conversion.
  • Late binding is difficult to convert to C# neatly and correctly

Old style website rather than Web app, try this https://github.com/icsharpcode/CodeConverter/issues/977#issuecomment-1381002321

C# - VB

In most cases, if you aren't absolutely sure it's right for your situation, I wouldn't recommend moving serious production code from C# to VB en masse.

  • The language is a second class citizen with fewer features, tools and developers. It also has a whole collection of subtle quirks which can hide issues and make it very hard to write reliable, maintainable, performant code
  • Surveys show it's one of the most 'dreaded' languages.
  • Because of the above, there has been less demand for conversion in this direction and hence the conversion quality is worse (e.g. Recent c# features aren't well supported)

The conversion in this direction is mainly useful for:

  • Minimal maintenance of an existing VB codebase (e.g. Convert a stack overflow snippet to integrate)
  • Learning C# for someone who knows VB
  • Individual projects
  • A safety net - knowing you could convert back to VB after a while if finding time to learn C# is proving difficult (obviously you'd only need to convert back the bits that have changed since original conversion)