VB.NET to C# Conversion Hints, Tips and Gotchas
If you're a VB.NET developer learning C# or converting your VB code to C#, here are a few hints, tips and gotchas.
But first, let me share a few important links with you:
VB.NET and C# Comparison - This is one of the most accurate and complete charts I've seen comparing VB.NET with its C# equivalent.
Convert VB.NET to C# and Convert C# to VB.NET - developerFusion provides these free online utilities to automatically convert VB.NET to C# and C# to VB.NET. It also supports the .NET 3.5 framework. There is no download required. Just simply use the online form. Telerik also provides a utility to Convert VB to C# or C# to VB. However, Linq is not yet supported in either converter as of this writing.
LearnVisualStudio.net provides free Cheat Sheets for "C# Language Basics Cheat Sheet" and "Visual Basic Language Basics Cheat Sheet." The links to the zip files can be found at the bottom of the home page.
I'll admit I've only been working with C# since 2007 and the majority of my projects have been in VB.NET. But I finally decided to write this post on some of the gotchas I have found when working with C# versus VB.
Option Strict On
By default, VB.NET sets Option Strict Off which allows backward compatibility with older Visual Basic legacy code. C# was originally written with the same type checking functionality as is performed in VB with Option Strict On. Therefore when converting your VB to C#, there is no option for Option Strict On.
For further information on OPTION STRICT ON in VB.NET, please see this article by Michael McIntyre.
References and Namespace Gotchas
C# is a lot more picky about referencing namespaces. For instance, in VB.NET you can access the Drawing.Colors like so without including the namespace:
validator.ForeColor = Drawing.Color.BlueViolet
However, in C#, even if you include the System namespace:
using System;
you cannot access a Drawing.Color member like so:
validator.ForeColor = Drawing.Color.BlueViolet;
you must use:
using System.Drawing;
and access the colors this way:
validator.ForeColor = Color.BlueViolet;
So even though you are "using System;" you would expect that you could use the Drawing namespace by calling Drawing.Color.BlueViolet as you can in VB. But it seems C# requires the namespace be added in a using directive and then you can call the class and its members. If any C# gurus have any further comments or links to shed more light on this, I'd appreciate it.
With Construct
There is no With construct in C#:
VB:
With validator
.ForeColor = Drawing.Color.BlueViolet;
End With
C#:
validator.ForeColor = Color.BlueViolet;
CInt versus (int) versus Convert.ToInt32
In VB.NET you can use CInt() for data type conversions:
If CInt(myString) <> NUMERICCONSTANT Then
Of course this will also work:
If (Convert.ToInt32(myString) <> NUMERICCONSTANT ) Then
However, in C#, this will error:
if ((int)myString != NUMERICCONSTANT)
But this will work:
if (myString != Convert.ToString(NUMERICCONSTANT))
See this article for a great comparison of String to Integer Conversion Methods in VB.NET.
Microsoft.VisualBasic Namespace
There are a few functions that are not available in C#. However, you can accomplish this same functionality in C# by including the Microsoft.VisualBasic Namespace. In your C# project, add a Reference to the Microsoft.VisualBasic component. Then add this directive to your class:
using Microsoft.VisualBasic;
Now you can produce the equivalent of this VB code:
If IsNumeric(myString) Then
in C#:
if (Information.IsNumeric(myString)) {
Also, this VB:
Microsoft.VisualBasic.Chr(9)
Can now be used in C# as:
Strings.Chr(9)
Other examples using Left and Len:
VB:
clientPath = Left(validFile.FileName, Len(validFile.FileName) - Len(validFile.GetName()))
C#:
clientPath = Strings.Left(validFile.FileName, Strings.Len(validFile.FileName) -
Strings.Len(validFile.GetName()));
DateTime can't be Declared as a Constant in C#
In C#, a Date cannot be declared as a constant.
VB:
Public Const INVALIDDATE As Date = #1/1/1753#
However, in C#, you may reproduce the same functionality by using either of these:
C#:
public readonly DateTime INVALIDDATE = DateTime.Parse("01/01/1753");
or
public static readonly DateTime INVALIDDATE = Convert.ToDateTime("01/01/1753");
() and Method Calls
In VB you can get away with calling a method call without ()'s. However, C# requires () after method calls.
For instance, this will work in VB:
control.GetType
But in C#, you must have the parens:
control.GetType()
Enumeration Conversions
In VB if you want to retrieve the numeric value of an enumerator, by default the enumerator returns the numeric value:
Enum Layout
Green = 1
Blue = 2
End Enum
Layout.Green will return 1.
Layout.Green.ToString() will return "Green"
C# does the opposite.
Layout.Green will return "Green"
To retrieve the numeric value, you must convert it to a numeric value first:
Convert.ToInt32(Layout.Green)
or:
(int) Layout.Green
In VB if you wish to retrieve the string equivalent of the numeric value, you must first convert the enumerator to an int, then convert the returned value to a string. You might do it this way, which won't work in C#:
CInt(Layout.Green).ToString
But in C#, the equivalent is:
Convert.ToString(Convert.ToInt32(Layout.Green))
Select / Case versus Switch / Case and Constants
In C#, the Switch/Case requires constants, so forget using the Switch / Case with your enumerator comparisons.
In VB, you can do this:
Select Case layoutName
Case Layout.Green.ToString
Return CInt(Layout.Green)
End Select
But in C#, the converters will convert it to this, which is not supported and will error:
switch (layoutName) {
case Layout.Green.ToString:
return (int)Layout.Green;
}
Instead, you'll need to convert your switch statement to an if/else statement:
if (layoutName == Convert.ToString(Layout.Green))
return Convert.ToInt32(Layout.Green);
So in C#, only constants will work, such as:
case 25:
or
case "male":
... et cetera.
CStr versus (string)
VB:
If CStr(myID) <> "25" Then
C#:
if ((string)myID != "25")
Linebreaks with Microsoft.VisualBasic.Chr(13) versus Environment.NewLine
If you have been using Microsoft.VisualBasic.Chr(13) to achieve a line break when creating javascript blocks, for instance, this will not work in C# unless you create a reference to the Microsoft.VisualBasic component and change it to Strings.Chr(13).
However, for both VB and C# you can achieve the same effect by using Environment.NewLine.
Global Constants
In VB, you can create Global Constants using a Public Module and call the constant directly by name if you include the namespace. In C#, you must include the class name when using the constant.
For instance, in VB, you can create a public module:
Public Module MyConstants
Public Const SUCCESS As Integer = 1
End Module
Then throughout your application you can use SUCCESS in any class as a global constant.
In C#, you must define a public static class:
public static class MyConstants
{
public const int SUCCESS = 1;
}
And when using the constant, preface it with the class name:
MyConstants.SUCCESS
VB:
Return (value <> SUCCESS)
C#:
return (value != MyConstants.SUCCESS);
Keywords
When using the code converters, sql keywords will be prefaced with @ in C#. For instance the "from" key word:
VB:
byval from as string
C#:
string @from
I would suggest changing variable names to non-keywords, such as:
string fromname
Web.UI.Control
In VB you can have this:
Dim myControl As Web.UI.Control = control.Parent
In C# the equivalent is:
Control myControl = control.Parent;
If you have any further comments to share, please do.
Educate Me! And may your dreams be in ASP.NET!
Nannette Thacker