Blaze

Back Again

 

From VB.NET to C# and Back Again [By Darren Neimke and Scott Mitchell ]

Introduction
In classic ASP, ASP pages could be developed using a number of different scripting languages, such as VBScript, JScript, PerlScript, and even Python. In ASP.NET, developers can use an even wider array of programming languages, from COBOL.NET to Perl.NET, to even crazier languages, like Objective CAML.NET. ASP.NET Web pages can also be created using Visual Basic.NET, C# (a Java-like language), and JScript.NET.

 

With classic ASP, the most popular scripting language, by far, was VBScript. Nearly every code example you'll find on the Web or in a book on ASP uses VBScript. With ASP.NET, however, a large number of developers are starting to use C#, Microsoft's newest language offering. As explained by Anders Hejlsberg (creator of C#), C# is Java-like language that borrows the good parts of Java and C/C++ and removes the bad parts. In the end, C#'s syntax is a lot like Java's (of which JScript is derived from, so if you're familiar with JScript, moving to C# will be easy enough).

In any case, as more and more developers begin using C#, more and more ASP.NET examples using C# will appear on the Web and in books. In my latest book, ASP.NET: Tips, Tutorials, and Code, all of the code examples are provided in both C# and VB.NET. Many ASP.NET Web sites have sections that show code exclusively in C#. While those familiar with Java, C/C++, or JScript may find this trend toward C# code samples a pleasant one, developers who have been using Visual Basic their entire career may be a bit disconcerted. They may find a perfect article showing C# code to accomplish some task they need to accomplish, but, if they don't understand C#, the code will look like gobbledygook to them. The same thing goes for developers who are fluent with Java and may be flabbergasted when examining a chunk of VB.NET code.

Ultimately, it is the .NET Framework of Classes that provides the functionality to perform tasks, while the languages themselves - VB.NET, C# etc. - are simply used to connect into it. For example, if you were connecting to a Microsoft Access database, you'd use the OleDbConnection class in the System.Data.OleDb namespace of the .NET Framework. (If you are unfamiliar with the .NET Framework you may wish to read this short summary on the .NET Framework.) Since the classes and methods used by an ASP.NET Web page, regardless of what language it is written in, are the same, the only differences between a C# and VB.NET code is its syntax. This article, then, will examine the syntactical differences between C# and VB.NET, and serve as a means for easily converting from one language to another.

Preliminary Syntactical Differences Between C# and VB.NET
One of the major differences between VB.NET and C# is that C# is case-sensitive while VB.NET is not. That is, in VB.NET the variable strName can be defined as strName and used throughout the ASP.NET Web page as strname, StrName, or any other case combination. In C#, however, case matters, so strname and StrName are considered two different variables. Where this really can be confounding is when using classes and methods in the .NET Framework. For example, notice the following statement written in VB.NET syntax:

response.write("Hello, World!")

However, in the .NET Framework the Response object is defined as Response (note the capital R) and the Write method is capitalized too. Hence, in C# code you'd need to have:

Response.Write("Hello, World!");

If you did not capitalize the R and W you would receive an error message when trying to view the ASP.NET Web page through a browser.

In every programming language, two very important things are the statement delimiters and block delimiters. Statement delimiters are the delimiters used to separate each statement from one another. Note the semicolon at the end of the above C# example; in C#, the semicolon is the statement delimiter. In VB.NET, each statement is delimited by a carraige return, meaning, essentially, each line of code goes on its own line. Since C#'s statement delimiter is the semicolon (;), at the end of each statement you must have a semicolon. A block is a set of grouped statements. For example, if you have an If statement in VB.NET with the following form:

If booleanValue then
            Statement1
            Statement2
            ...
            StatementN
            End If
            

The statements Statement1 through StatmentN are all in a block. Note that the block is marked by the beginning If statement and the closing End If. In C#, curly braces are used as block delimiters. That is, in C# our if code would look like:

if (booleanValue)
            {
            Statement1
            Statement2
            ...
            StatementN
            }
            

Note that if must be lowercase, and that there is no then keyword. Also, the booleanValue must be surrounded by parenthesis. These curly braces ({ ... }) are used whenever a block is needed in C#, such as bodies of functions, while statements, for statements, etc. Note that VB.NET uses more explicit block delimiters, such as Function ... End Function, While ... End While, For ... Next, etc.

Some other minor differences: in VB.NET we specify commented lines using the apostrophe ('); in C# we can have single line comments, marked by //, or we can create mutli-line comments using the delimiters /* and */. That is, everything between those delimiters is considered a comment.

Declaring Variables
In VB.NET variables are declared via the Dim statement, in the following syntax:

Dim VariableName as Type [ = value]

The VariableName is the name of the variable (such as strName, the Type is the type of the variable (such as Integer or String), and the = value is an optional addition, which sets the variable to a specified value. For example, if we wanted to create an Integer named iAge with an initial value of 23, we could do:

Dim iAge as Integer = 23

In C#, the syntax is just a little different. We omit the Dim statement and place the Type before the VariableName, like so:

Type VariableName [ = value];

// an example
int iAge = 23;

Note that there are some differences in the type names between C# and VB.NET. The following table lists some of the common data types in VB.NET and their equivalent names in C#. Realize, though, that despite these minor differences in the spelling of the data types that these data types map back to the same data types specified in the .NET Framework. That is, a VB.NET Integer and a C# int are both instances of the System.Int32 .NET Framework structure. In fact, instead of specifying iAge and Integer or int in the above examples, we could have said: Int32 iAge = 23; or Dim iAge as Int32 = 23, which would have had the same effect as declaring it an Integer or int.

Differences in Data Type Names
VB.NET C#
Integer int
String string
Single float

There are still many syntactical differences we need to examine between VB.NET and C#, including differences in operator, array, and function usage, declaration, and allocation. We'll examine all of these pertinent issues in Part 2.

In Part 1 we examined some of the primary differences between the syntax of VB.NET and C#. Additionally, we looked at how to two languages declared variables differently. In this part we'll look at each language's use of operators, arrays, and functions!


Examining the Operators
VB.NET and C# have roughly the same set of operators. For example, to perform addition between two numbers, use the + operator in either language. The one major difference is the string concatenation operator. VB.NET uses the ampersand (&), while C# uses the +. Both languages also have a short-hand notation for this - &= and +=, which takes a string on the left hand side and concatenates the string on the right hand side. That is, if we had:

// C# example...
someString += someOtherString;

' VB.NET example...
someString &= someOtherString

at the conclusion, someString would equal whatever value it equaled before we reached the line shown above, concatenated with the value of someOtherString More clearly, if someString initially equaled "Scott and someOtherString equaled "Mitchell", at the conclusion of the above line, someString would equal "Scott Mitchell".

Arrays in VB.NET and C#
Arrays in VB.NET and C# are created and managed a bit differently. First of all, to index an element in an array in VB.NET, you use parenthesis, as in the following example:

arrayVariable(index)

In C#, however, square brackets are used, like so:

arrayVariable[index]

When creating arrays in VB.NET, the syntax used is, essentially, the syntax used to create any variable. If you wanted to create an array named ages with 0 to n Integer elements, you'd do:

Dim ages(n) as Integer

Again, note that this would create a total of n + 1 elements (0 .. n). In C#, the array declaration is a bit different:

int [] ages = new int[n];

Note that we place the [] before the variable name; this indicates that ages is going to be an array. Next, we have to allocate n ints by saying = new int[n]. Note that this creates a total of n elements, elements indexed from 0 to n - 1! This is different than in VB.NET, which creates a total of one extra element when compared to the way C# does it.

Creating and Using Functions and Procedures
In VB.NET there are two classes of functions: those that return values and those that don't. Those functions that don't return values are called subroutines, and are created a bit differently than functions. In VB.NET, to create a function, which returns a value, use the following syntax:

Function FunctionName(arg1 as Type, ... argN as Type) as ReturnType
    ...
    Return someVariableOfReturnType
End Function

Note that when creating a function you must specify a return type at the end of the first line of the function declaration. Then, somewhere in the body of the function (usually at the end), you must return a value of the proper ReturnType. Functions, of course, can take zero to many input parameters, arg1 through argN, each with their own Type. A subroutine (or procedure, as it's sometimes called), is defined a bit differently:

Sub ProcedureName(arg1 as Type, ... argN as Type)
    ...
End Sub

Note that the Sub keyword is used instead of the Function keyword, and that no value need be returned.

In C#, to create either a function or a procedure (a function that doesn't return a value) you must use the following syntax:

ReturnType FunctionName(Type arg1, ... Type argN)
{
    ...
    return someVariableOfReturnType
}

In C# if you don't want the function to return a value, specify the ReturnType as void. Note that the function's body is delimited by the curly braces ({ ... }) and that, as with the VB.NET function, we must have a return statement, returning a variable of the proper type (with functions whose ReturnType is void no return is necessary). Also note that in the function arguments the Type comes before the arg name, just like when declaring variables in C#.

Casting
While it may help to think of a variable as nothing but a simple value, a variable can be formally defined by a number of properties, such as its value, scope, lifetime, and type. The type of a variable determines the set of legal values that it can be assigned; for example, a variable of type integer (Int32) can be assigned values from -231..231-1. When you attempt to assign two variables of unequivalent types, say assigning a string to an integer, a process called casting must occur.

Essentially, casting is the process of converting a variable from one type to another (from a string to an integer in our previous example). Casting comes in two flavors: implicit and explicit. Implicit casting, as the name implies, happens automatically; with explicit casting, extra syntax must be used to specify that a cast should occur. VB.NET allows for a lot of implicit casting, while C# requires casts to be explicit. For example, if we wanted to have an ArrayList of Integer values, and then wanted to work with a particular values, we need to use explicit casting in C#:

ArrayList ages = new ArrayList();
ages.Add(23);
int x = ages[0]; // ERROR: ages[0] returns an object - need to cast to int

However, the above code (in VB.NET syntax, of course) will work fine. To cast in C#, simply place a (DesiredType) section in front of the variable you wish to cast. To make the above code compile, we need to cast s to an int:

ArrayList ages = new ArrayList();
ages.Add(23);
int x = (int) ages[0]; // No error due to explicit cast to int

Not all types can be casted to other types. If you attempt to illegally cast a type, you will get an error message informing you that the cast is illegal. In VB.NET, explicit casting can be used via the CType function. The syntax is as follows:

VariableOfTypeConvertToType = CType(ObjectToCast, ConvertToType)

Now that we've examined the fundamental differences between VB.NET and C#, let's examine an actual exercise of translating an ASP.NET Web page from C# to VB.NET. We'll do this in Part 3.

 

In Part 2 we looked at more advanced differences between VB.NET and C#: namely the differences in operator usage; array usage, declaration, and allocation; and the functional differences. In this final part, we will (finally) look at a complete C# ASP.NET Web page and convert it to C#!

Putting the Pieces Together - Converting an Actual ASP.NET Web Page
Now that we've examined the major syntactical differences between VB.NET and C#, let's attempt to apply what we've learned and convert a C# ASP.NET Web page to VB.NET. The following code, written in C#, reads in the Products table from the GrocerToGo database into an OleDbDataReader, and then uses data binding to bind the data reader to a DataGrid. The code is as follows:

<% @Import Namespace="System.Data" %>
            <% @Import Namespace="System.Data.OleDb" %>
            <script language="c#" runat="server">
            void Page_Load(Object sender, EventArgs e)
            {
            // 1. Create a connection
            const string strConnString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
            "Data Source=C:\\Data\\GrocerToGo.mdb";
            OleDbConnection objConn = new OleDbConnection(strConnString);
            // You must open the db connection before populating the DataReader
            objConn.Open();
            // 2. Create a command object for the query
            const string strSQL = "SELECT * FROM Products";
            OleDbCommand objCmd = new OleDbCommand(strSQL, objConn);
            // 3. Create/Populate the DataReader
            OleDbDataReader objDR = objCmd.ExecuteReader(CommandBehavior.CloseConnection);
            // Do data binding
            dgProducts.DataSource = objDR;
            dgProducts.DataBind();
            }
            </script>
            <html>
            <body>
            <h1>The <code>Products</code> Table</h1>
            <asp:datagrid runat="server" id="dgProducts" ForeColor="White" BackColor="Navy"
            Font-Name="Verdana" BorderWidth="0" CellPadding="4"
            HeaderStyle-Font-Bold="True"
            HeaderStyle-Font-Size="Small"
            Font-Size="Smaller"
            HeaderStyle-BackColor="Gray"
            />
            </body>
            </html>
            
[View a live demo!]

One thing to notice that wasn't mentioned before: in the constant strConnString note that to specify a backslash (\) in a C# string, we must use two consecutive backslashes (\\). This is because the backslash is the C# escape character - that is, we can insert a newline character using \n, or tab using \t. Therefore, to let C# know that we want a plain-Jane backslash and not some escaped character, we have to use two backslashes.

Now, to convert this to VB.NET! First note that all of the code in the HTML section (between the <html> and the </html>) will need no changes - we just need to concern ourselves with the server-side script block (or code-behind page, if you're using that technique). First, let's change all of the function statements to VB.NET-proper function statements. That is:

void Page_Load(Object sender, EventArgs e)
{
   ...
}

becomes:

Sub Page_Load(sender as Object, e as EventArgs)
   ...
End Sub

Note that we created a Sub since the C# function's return value was void. We also got rid of the curly braces, replacing the last one with End Sub. Finally, in the subroutine's arguments, we reordered the Type and arg names such that the arg name comes first followed by the Type. Next, we'll want to do some ticky-tack changes, such as renaming all of the constant delimiters in C#, //, to their VB.NET equivalents, ', removing all of the semicolons, and changing the C# string concatenation operator of + to the VB.NET operator, &. Next, let's change all variable (and constant) declarations from the C# format of Type VariableName to the VB.NET format of Dim VariableName as Type; for example, we'll make the following (among other) changes:

const string strSQL = "SELECT * FROM Products"; -- becomes --
Const strSQL as String = "SELECT * FROM Products"

... and ...

OleDbCommand objCmd = new OleDbCommand(strSQL, objConn); -- becomes --
Dim objCmd as OleDbCommand = New OleDbCommand(strSQL, objConn)

Once we complete this we are, miraculously, done! The use of methods and objects from the .NET Framework (such as the OleDbCommand class, are identical regardless of the language being used. Note that translating from VB.NET to C# requires a bit more attention when it comes to the casing of classes and methods, since C# is case-sensitive. The final VB.NET translation can be seen below:

<% @Import Namespace="System.Data" %>
            <% @Import Namespace="System.Data.OleDb" %>
            <script language="VB" runat="server">
            Sub Page_Load(sender as Object, e as EventArgs)
            '1. Create a connection
            Const strConnString as String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
            "Data Source=C:\Data\GrocerToGo.mdb"
            Dim objConn as New OleDbConnection(strConnString)
            objConn.Open()
            '2. Create a command object for the query
            Const strSQL as String = "SELECT * FROM Products"
            Dim objCmd as New OleDbCommand(strSQL, objConn)
            '3. Create/Populate the DataReader
            Dim objDR as OleDbDataReader
            objDR = objCmd.ExecuteReader()
            dgProducts.DataSource = objDR
            dgProducts.DataBind()
            End Sub
            </script>
            <html>
            <body>
            <h1>The <code>Products</code> Table - Looks Nice!</h1>
            <asp:datagrid runat="server" id="dgProducts" ForeColor="White" BackColor="Navy"
            Font-Name="Verdana" BorderWidth="0" CellPadding="4"
            HeaderStyle-Font-Bold="True"
            HeaderStyle-Font-Size="Small"
            Font-Size="Smaller"
            HeaderStyle-BackColor="Gray"
            />
            </body>
            </html>
            
Pretty neat, eh? Essentially, translating from one language to another is not difficult, especially if you have a nice algorithm to aid in the translation. In fact, you could take this one step further and write a translator that morphed VB.NET code to C# code, and back again! I do strongly encourage you to practice such translations every now and then - it will make you more familiar with both VB.NET and C# and, in the end, make you a more knowledgeable developer!

Happy Programming!

 

  • By Darren Neimke and Scott Mitchell
  • posted on 2006-06-14 12:47  Blaze  阅读(816)  评论(0编辑  收藏  举报

    导航