Choosing Between C# and VB

Here’s a question most .NET developers have to deal with: C# or VB?

This can be a pretty heated debate; people love to defend the tools they love.  Once you get down to work, though, both languages are very similar.  They both have access to the same libraries and tools, they both have full support from Microsoft and enormous developer communities, and they both get the job done well.

But there are differences.  Let’s look at some of the more important ones:

C# Only: Better syntax

Let’s face it: C-style syntax is better than BASIC-style syntax.  You just can’t argue this one.  BASIC is too wordy; C lets you focus on what matters: your code.  Sure, both languages have code generation and IntelliSense and code snippets, and yes, you can come up with examples where VB code is shorter and more elegant than C#.  But for the most part, it’s pretty hard to argue that VB syntax is designed for experienced developers.

This isn’t as big a deal as you might think.  There’s no scenario where C# syntax is much faster to code in than VB syntax (assuming you have Visual Studio to back you up). But, C# is just a tiny bit faster in 500 different ways, and it adds up.  There are other factors to consider in choosing a language, of course, but this remains a very compelling argument.

C# Only: More advanced development community

VB is generally easier for new developers to pick up, and often allows faster development.  This might sound like an advantage to VB, but there’s a huge counter-argument: the C# community tends to be more advanced than the VB community, and is often more respected.  An experienced developer who prefers VB might have a hard time convincing others that VB can sometimes be a better choice, but a developer who only knows VB will be laughed right out of the room.

If you’re trying to decide on a single language to learn, don’t.  You need to understand at least half a dozen languages and technologies to get anything done in the real world: HTML, CSS, Java(script), XML, SQL, C(++), and more. And if you’re going to be a .NET developer, learn C# and VB.

C# Only: Unsafe code

The .NET world is wonderful, but sometimes you need to drop back to the frightening world of direct memory management.  You can usually accomplish the same tasks in VB through managed code, and even in the pre-.NET world, VB could still read and write to locations in memory directly, but there’s no getting around the fact that C# is a better choice if you can’t imagine a world without pointers.

C# Only: Checked / Unchecked

C# also lets you control exactly when overflows and underflows are caught and when they’re ignored.  In the managed world, it’s pretty tough to argue that overflow can actually be useful, but there’s a lot of legacy code – and legacy developers – out there who depend on things working they way they always have.

C# Only: Iterators

C# also lets you work with iterators.  Sure, VB knows how to iterate, but C# has a bit of extra power and flexibility here.  Check this out:

public IEnumerator<string> GetEnumerator()
foreach (string s in strings)
yield return s;

Iterators essentially let a function return values in the middle of the function.  This is a great tool, and one that’s hard to get used to not having when coding under VB.

C# Only: Refactoring

Only C# includes refactoring support build right into the IDE.  These are a collection of extra tools and commands that make development easier and faster, and C# developers are often shocked to learn that VB doesn’t include these features.  True, there are enhanced refactoring add-ins available for both languages that do a better job than what’s built into the C# IDE, but you can’t beat having something ready to go right out of the box.

VB Only: Handles and WithEvents

In C#, you have to hook up events through code.  Sure, there’s designer support available, but it makes for a more complicated project.  In VB, the Handles keyword does all this work for you.  When it comes to creating a UI for your application, this is a really big deal and makes VB developers significantly more productive: things are simpler, and you just don’t have to write as much code.  When it comes to writing business logic and other UI-less code, this doesn’t really matter very much.

VB Only: With

VB offers the With structure.  Not only is this convenient, it also improves performance.  Take this bit of C# code:

System.Text.StringBuilder sb = new StringBuilder();
sb.AppendLine("FileName: " + System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
sb.AppendLine("Memory size: " + System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleMemorySize.ToString());
sb.AppendLine("Entry point: " + System.Diagnostics.Process.GetCurrentProcess().MainModule.EntryPointAddress);

And now look at it under VB:

Dim sb = New System.Text.StringBuilder
With System.Diagnostics.Process.GetCurrentProcess.MainModule
sb.AppendLine("File name: " + .FileName)
sb.AppendLine("Memory size: " + .ModuleMemorySize)
sb.AppendLine("Entry point: " + .EntryPointAddress)
sb.AppendLine("Debug: " & .FileVersionInfo.IsDebug)
End With

That’s just less code.  Less code is easier to write, read, and maintain.

This example might be a little contrived:  in the real world, you’d just declare a new variable (and give it a short name).  My point, though, is that with VB, you don’t have to do this.

VB Only: My

The My class is pure convenience.  There’s nothing under My that can’t be found elsewhere in the framework, but it makes it very easy to access a lot of calls in the framework that were previously difficult to find and use.  Have a look at this:

If My.User.IsInRole(ApplicationServices.BuiltInRole.Administrator) Then
My.Computer.Network.DownloadFile("", "C:\")
My.Computer.Network.DownloadFile("", My.Computer.FileSystem.SpecialDirectories.Desktop)
End If
Catch ex As Exception
End Try

C# can do all this, of course, but it’s going to take more code.  That said, a lot of the functionality under My is just there to help beginners find what they’re looking for.  There are a few things here that are invaluable (such as the My.Settings class), but generally, C# developers won’t miss this too much.

VB Only: XML / Date Literals

Date literals have been around in VB forever, and while it’s debatable how often you should be hardcoding dates in code, it’s still nice to have the option (although it’s too bad the illogical American MM/dd/yyyy format is used).  XML literals, on the other hand, are a huge leap forward.  Once you work with XML in VB for a while, going back to C# will be pretty painful.  Have a look at this code, for example:

Dim allScreens = From s In Screen.AllScreens
Select <Screen>
<Device><%= s.DeviceName %></Device>
<Width><%= s.Bounds.Width %></Width>
<Height><%= s.Bounds.Height %></Height>
<BitsPerPixel><%= s.BitsPerPixel %></BitsPerPixel>

Dim document = <?xml version="1.0" encoding="utf-8"?>
<%= allScreens %>


That’s insanely, ridiculously simple.  And the IntelliSense support here is amazing; you really have to try it to understand how beneficial this is.  If you work with XML much, this is a really compelling reason to pick VB over C#.

VB Only: Late-binding and COM

This is another big one.  VB allows developers to use late-binding.  Essentially, this means a developer can call a member on a variable declared simply as Object.  At run-time, the compiler looks at the object, and if the call makes sense, it runs.  If it doesn’t make sense, an error occurs.  In the theoretical world of pure managed code and beautifully designed classes, using such a feature would be considered poor code.  In the real world, though, it’s nice to have this option available.  And where it really makes a world of difference is when you’re working with COM objects.  Again, let’s compare.  Here’s some VB code that automates Microsoft Word a bit:

With CreateObject("Word.Application")
With .Documents.Add()
.Range.Text = Clipboard.GetText()
End With
End With

And here’s the same code in C# (brace yourself!):

object app = Activator.CreateInstance(Type.GetTypeFromProgID("Word.Application"));
app.GetType().InvokeMember("Visible", System.Reflection.BindingFlags.SetProperty, null, app, new object[1] { true });
object docs = app.GetType().InvokeMember("Documents", System.Reflection.BindingFlags.GetProperty, null, app, null);
object doc = docs.GetType().InvokeMember("Add", System.Reflection.BindingFlags.InvokeMethod, null, docs, null);
object range = doc.GetType().InvokeMember("Range", System.Reflection.BindingFlags.InvokeMethod, null, doc, null);
range.GetType().InvokeMember("Text", System.Reflection.BindingFlags.SetProperty, null, range, new object[1] { Clipboard.GetText() });
doc.GetType().InvokeMember("SaveAs2", System.Reflection.BindingFlags.InvokeMethod, null, doc, new object[1] { "clipboard.docx" });
doc.GetType().InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, doc, null);
app.GetType().InvokeMember("Quit", System.Reflection.BindingFlags.InvokeMethod, null, app, null);

As you can see, working with COM in this fashion is really, really painful under C#.  In fact, only through reflection is this even possible!  This has been improved somewhat with the recent addition of the dynamic type in C# 4.0, if you’re able to take advantage of the latest version.

VB Only: Implicit Conversions

In C#, all type conversions must be performed explicitly.  In VB, most simple conversions are performed automatically by the compiler.  This means you can add 2 and 2.0, and it means you don’t need to type .ToString() anywhere near as often.  It can save a lot of time, but can also cause bugs if the conversion wasn’t expected.  Note that you don’t want to give this feature to new developers; they will only get themselves into trouble with it.  It’s great to have conversions done implicitly, but only if you already understand what’s going on under the hood.

VB Only: Better IntelliSense and Error List

In VB, the IDE is much faster at updating IntelliSense, the Error list, and other tools.  Under C#, you often need to rebuild your project to update the Error list and certain other features.  And, IntelliSense is just all-around better under VB.  This might not seem like a drastic difference, but it saves you a second or two countless times a day.  You’ll certainly notice this when moving between the languages frequently.

Other Differences

I think that’s about it for major features available in only one language.  There are a plethora of other small arguments to make, but none that really have much of an overall impact on choosing a language.  There are, of course, many other major differences that don’t really have a clear advantage one way or the other.  Namespaces are handled differently.  VB offers project-level Imports, while C# is better at helping you manage file-level ‘using’ statements.  C# offers static classes, while VB offers Modules.  Commenting works differently.


There is one area where C# is really the only sensible choice:

  • Unsafe code

There are three areas where VB has a clear advantage over C#:

  • Working with COM (although C# 4.0 narrows the gap)
  • Working with XML
  • Developing UI

Outside of these areas, it all comes down to personal preference.  C# has the better syntax and a more advanced community, while VB offers a range of features and aids not available to C#.

But remember: it’s not about the tool.  It’s about what you do with it.


  1. One thing that you missed about VB, which I really miss in C# and C++ is the realloc() function. In VB it is redim preserve.

    1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a .Net developer learn from Dot Net Training in Chennai. or learn thru ASP.NET Essential Training Online . Nowadays Dot Net has tons of job opportunities on various vertical industry.

      or Javascript Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry.

  2. After slicing your hemp twine provide the hemp thread and lower 10 items only one foot long.

  3. After slicing your hemp twine provide the hemp thread and lower 10 items only one foot long.

  4. After slicing your hemp twine provide the hemp thread and lower 10 items only one foot long.

  5. After slicing your hemp twine provide the hemp thread and lower 10 items only one foot long.

  6. After slicing your hemp twine provide the hemp thread and lower 10 items only one foot long.


Copyright © 2010 Paul Guenette and Matthew Sleno.