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:
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.

May your dreams be in ASP.NET!

Nannette Thacker

 

5 Comments

  • Fantastic! This article saved me hours of research!

    Thanks!,

    PHil K.

  • I have a problem on VB, would like to ask pinion from you.

    If Len(TxtLog.Text) >= 10000 Then
    TxtLog.Text = Mid(TxtLog.Text, 5000)
    End If

    What does this mean?

  • Fiona,

    The first statement is saying if the length of your text is greater than 10000 characters, then...

    The second statement is saying, starting at position 5000 in your txtlog.text file, return the remaining characters.

    I would guess this is designed to keep your txtLog from filling up. Likely new logs are appended on the end, so if it gets too long, they want to take the bottom of the txtLog and replace it, eliminating the first 5000 characters.

    Try google:
    asp.net mid function

    to find functions in asp.net and see how they're used.


  • Really awesome article.

  • Really helpful article Nanette.
    It appears just when I needed it!

    regards,

    Ted

Comments have been disabled for this content.