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 want to share 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. C# requires the namespace be added in a using directive and then you can call the class and its members.
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:
cont
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.
May your dreams be in ASP.NET!
Nannette Thacker