Topic: Differences between VB.Net & C#
Share/Save/Bookmark
Abstract
This white paper discusses the differences in syntax between the Microsoft® Visual Basic .NET™ and Microsoft® Visual C# .NET™ programming languages. Visual Basic .NET and Visual C# .NET differ in terms of case sensitivity, variable declaration and assignment, data types, statement termination, statement blocks, use of parentheses versus brackets, operators, conditional statements, error handling, overflow checking, parameter passing, late binding, ways of handling unmanaged code, and keywords.
 
INTRODUCTION
Because of the past differences between Microsoft® Visual Basic™, Microsoft® Visual C™, and Microsoft® Visual C++™, many developers have the impression that Microsoft® Visual C# .NET™ is a more powerful language than Microsoft® Visual Basic .NET™. Some developers assume that many things that are possible in Visual C# .NET are impossible in Visual Basic .NET, just as many things that are possible in Microsoft® Visual C™ 6.0 and earlier or Microsoft® Visual C++™ 6.0 and earlier are impossible in Microsoft® Visual Basic™ 6.0 and earlier. This assumption is incorrect. Although differences exist between Visual Basic .NET and Visual C# .NET, they are both first-class programming languages that are based on the Microsoft® .NET Framework, and they are equally powerful. Visual Basic .NET is a true object-oriented programming language that includes new and improved features such as inheritance, polymorphism, interfaces, and overloading. Both Visual Basic .NET and Visual C# .NET use the common language runtime in the .NET Framework, and almost no performance issues now exist between them. Visual Basic .NET may be oriented more toward ease of use by providing features such as late binding, and Visual C# .NET may have a few more "power" features, such as handling unmanaged code, but the differences are very small compared to what they were in the past.
This document discusses differences between Visual Basic .NET and Visual C# .NET. However, the key point to keep in mind is that .NET is intended to be language-independent. The choice between Visual Basic .NET and Visual C# .NET is typically based on your personal preference and past experience; for example, it is easier for Visual Basic 6.0 developers to use Visual Basic .NET, and for Visual C++ and Java programmers to use Visual C# .NET. The existing experience of a programmer far outweighs the small differences between the two languages.
 
Case Sensitivity
Identifier names in Visual Basic .NET are not case-sensitive, but identifier names in Visual C# .NET are. This primarily presents a problem when you write code, and is not an issue in debugging a program that already compiles.
 
Variable Declaration and Assignment
Variables in Visual Basic .NET are declared with the variable before the data type. In Visual C# .NET, the data type precedes the variables.
Visual Basic .NET                         Visual C# .NET
 
Dim i, j As Integer                       int i, j;
Dim i As Integer = 7                      int i = 7;
Dim i(6) As Integer                       int[] i = new int[6];
or
Dim i() As Integer = New Integer(6) {}   
Dim con As SqlConnection                  SqlConnection con;
Dim x As New Y("ABC")                     Y x = new Y("ABC");
or
Dim x As Y = New Y("ABC")                
Data Types
 
Data Types
Simple data types have different names in Visual Basic .NET and Visual C# .NET. For example, Integer in Visual Basic .NET is int in Visual C# .NET. However, System.Int32, the .NET Framework base type for which Integer and int are aliases, can be used in both languages. Visual C# .NET also supports the signed byte, unsigned short, unsigned int, and unsigned long data types, which are not available in Visual Basic .NET.
 
The following table lists the different data type names in each language and the base types for which they are aliases.
Visual Basic .NET             Visual C# .NET          .NET Framework
Boolean                       bool                    System.Boolean
Byte                          byte                    System.Byte
Short                         short                   System.Int16
Integer                       int                     System.Int32
Long                          long                    System.Int64
Single                        float                   System.Single
Double                        double                  System.Double
Decimal                       decimal                 System.Decimal
Date                          System.DateTime         System.DateTime
String                        string                  System.String
Char                          char                    System.Char
Object                        object                  System.Object
n/a                           sbyte                   System.Sbyte
n/a                           ushort                  System.UInt16
n/a                           uint                    System.UInt32
n/a                           ulong                   System.UInt64
 
Properties
            Visual Studio VB Net                      Visual Studio C# Net
            Public Property ID() As Integer           public int ID
             Get                                     {
                  Return _ID                                get { return _ID; }
              End Get                                       set { _ID = value; }
              Set(ByVal Value As Integer)             }
                  _ID = Value
             End Set
            End Property
 
Statement Termination
Statements in Visual Basic .NET are terminated by the end of the line. You can use the colon (:) to put multiple statements in a line, and you can use the line continuation (_) character to make a statement span several lines.
 
Statements in Visual C# .NET are terminated by the semicolon (;). You can use multiple statements per line, and statements can span multiple lines.
Visual Basic .NET                         Visual C# .NET
A = 5                                     A = 5;
B = 7 : C = 8                             B = 7; C = 8;
MySub (Arg1, _                            MySub (Arg1,
             Arg2, _                      Arg2,
             Arg3)                        Arg3);
 
Statement Blocks
Visual Basic .NET does not use arbitrary statement blocks. Instead, certain keywords that have a specialized terminating statement are used instead of the statement blocks.
 
In Visual C# .NET, braces ({}) are used to delimit a statement block; otherwise, a single statement is assumed.
 
Visual Basic .NET                         Visual C# .NET
If A = 5 Then                             If (a == 5)
 DoSomething()                           {
 DoSomethingAgain()                            DoSomething();
End If                                          DoSomethingAgain();
                                          }
                                          or
     
                                          if (a == 5)
                                                DoSomething();
                                                DoSomethingAgain(); //This is not part of                     
                                                                    //the if statement.
 
Use of () vs. [ ]
Visual Basic .NET uses parentheses () to delimit array elements, function arguments, and property indexes.
 
Visual C# .NET uses parentheses () to delimit function arguments, and brackets ([]) to delimit array elements and property indexes.
 
Purpose           Visual Basic .NET             Visual C# .NET
Declare           Dim a() As Long               int[] x = new int[5];
an array          Dim a(3, 5) as Integer 
 
Initialize an     Dim a() As Long = {3, 4, 5}   int[] x = new int[5] {1, 2, 3, 4, 5};
array      
 
Reallocate array Redim                         n/a
 
Functions         X= A(5)                       MySub(A, B, C);
Arguments         MySub (A, B, C)
     
Property Indexes Y = MyDataSet.Tables_        Y = MyDataSet.Tables["Author"].
                  ("Author").Rows(5)._          Rows[5].Columns["AuthorID"]
                  Columns("AuthorID")    
 
Operators
The operators that are used in Visual Basic .NET and Visual C# .NET are quite different. The following table lists the main operators. This information can also be found in the Microsoft® Visual Studio .NET™ documentation.
 
Operator                Visual Basic .NET             Visual C# .NET
Additive          
Addition                +                             +
Subtraction             -                             -
Multiplicative          
Multiplication          *                             *
Division                /                             /
Integer division        \                             / (depending on the operands)
Modulus                 Mod                           %
   (division
    returning only
    the remainder)           
Exponentiation          ^                             n/a
Assignment       
Assignment              =                             =
                        += -= *= /*                += -= *= /*
Integer division        \=                            /= (depending on the operands)
Concatenate             &=                            +=
Modulus                 n/a                           %=
Left shift              n/a                           <<=
Right shift             n/a                           >>=
Bitwise AND             n/a                           &=
XOR                     n/a                           ^=
OR                      n/a                           |=
Relational and equality       
Less than               <                             <
Less than or equal to   <=                            <=
Greater than            >                             >
Greater than            >=                            >=
or equal to
Equal                   =                             ==
Not equal               <>                            !=
Compare two             Is                            ==
   object reference
    variables    
Compare object          TypeOf x Is Class1            x is Class1
reference type   
Compare strings         =                             == or String.Equals()
Concatenate strings     &                             +
Shortcircuited          AndAlso                       &&
    Boolean AND  
Shortcircuited          OrElse                        ||
    Boolean OR   
Shift       
Left shift              n/a                           <<
Right shift             n/a                           >>
Scope resolution       
Scope resolution        .                             ., base
Postfix           
Type cast               Cint, CDbl, …, CType          (type)
Member selection        .                             .
Postfix increment       n/a                           ++
Postfix decrement       n/a                           --
Unary       
Indirection             n/a                           * (unsafe mode only)
Address of              AddressOf                     & (unsafe mode only)
Logical NOT             Not                           !
One's complement        Not                           ~
Prefix increment        n/a                           ++
Prefix decrement        n/a                           --
Size of type            n/a                           sizeof
Bitwise           
Bitwise NOT             Not                           ~
Bitwise AND             And                           &
Bitwise XOR             Xor                           ^
Bitwise OR              Or                            |
Logical           
Logical AND, OR         And                           &&
Logical OR              Or                            ||
Conditional       
Conditional             IIf                           ?:
Pointer to member       
Pointer to member       n/a                           . (Unsafe mode only)
 
Conditional Statements
The following table lists the differences in the conditional statements that Visual Basic .NET and Visual C# .NET use.
 
Conditional Statement   Visual Basic .NET            Visual C# .NET
Decision structure      Select Case …, Case,          switch, case, default,
(selection)             Case Else, End Select
 
Decision structure      If … Then, ElseIf … Then,     if, else
(if … then)             Else, End If
 
Loop structure          While… End While,             do, while, continue
(conditional)           Do [While, Until] …,
                        Loop [While, Until]    
 
Loop structure          For …, [Exit For,] Next       for, foreach
(iteration)             For Each …,
                        [Exit For,] Next 
                       
                        For i As Integer = 0 _        for (int i = 0; i < List.Count - 1; i++)
                               To list.Count - 1      {
                        Next                          }
 
 
 
Control flow statement Exit, GoTo, Stop, End,        continue, goto, return,
                        break,                        throw
 
Error Handling
Unstructured error handling is for backward compatibility. Visual Basic .NET supports both structured and unstructured error handling, but Visual C# .NET supports only structured error handling
 
Purpose                 Visual Basic .NET             Visual C# .NET
Structured error        Try                           try,
handling                …                             catch,
                        Catch                         finally,
                        …                             throw
                        Finally
                        …
                        End Try    
Unstructured error      On Error GoTo …               n/a
handling                On Error Resume Next   
 
Overflow Checking
Visual Basic .NET has a project level setting to check for overflow. However, the checking can only be turned on and off at the project level, instead of at the level of an expression or a block of code. To turn overflow checking on and off, follow these steps:
1.    On the Project menu, click Properties.
2.    Under Configuration Properties, select Optimizations, and then select or clear Remove integer overflow checks.
Visual C# .NET statements can run in either a checked or an unchecked context. In a checked context, arithmetic overflow raises an exception error. In an unchecked context, arithmetic overflow is ignored and the result is truncated. This can be used on an expression or a block of code.
 
Parameter Passing
Visual Basic .NET uses ByVal for passing parameters by value, and uses ByRef for passing parameters by reference. Visual Basic .NET can also force parameters to be passed by value, regardless of how they are declared, by enclosing the parameters in extra parentheses. Visual Basic .NET also supports optional parameters, which are not available in Visual C# .NET.
Visual C# .NET does not have a way to pass reference types (objects) strictly by value. You can either pass the reference (basically a pointer) or a reference to the reference (a pointer to a pointer). Unmanaged Visual C# .NET methods can take pointers just like Visual C++ methods. To pass a parameter by reference, Visual C# .NET uses the ref keyword. To use a ref parameter, the argument must explicitly be passed to the method as a ref argument. The value of a ref argument is passed to the ref parameter.
 
Purpose                 Visual Basic .NET             Visual C# .NET
Pass by value           Public Sub ABC (ByVal         void ABC(int x)
                        y As Long)                    {
                         …                              ...
                        End Sub                       }
 
                        ABC(x)                        ABC(i);
 
                        ABC((x))
        
Pass by reference       Public Sub ABC(ByRef          void ABC(ref int x)
                        y As Long)                    {
                         …                              ...
                        End Sub                       }
 
                        ABC(x)                        ABC(ref i);
     
Optional parameter      Supported                     n/a
 
Late Binding
Both Visual Basic .NET and Visual C# .NET can implement implicit late binding through reflection. However, implementing late binding in Visual Basic .NET is much easier than in Visual C# .NET.
 
In Visual Basic .NET, as in Visual Basic 6.0, the Visual Basic compiler calls a helper method behind the scenes that uses reflection to obtain the object type. The arguments that are passed to the helper method cause the appropriate method to be invoked at run time. These arguments are the object on which to invoke the method, the name of the invoked method that is a string, and the arguments that are passed to the invoked method that is an array of objects. Additionally, you can implement late binding explicitly in code through reflection.
 
Imports System
Module Hello
   Sub Main()
      ' Set up variable.
      Dim helloObj As Object
      ' Create the object.
      helloObj = new HelloWorld()
      ' Invoke the print method as if it was early bound
      ' even though it is really late bound.
      helloObj.PrintHello("Visual Basic Late Bound")
   End Sub
End Module
 
In Visual C# .NET, implementing late binding is more difficult than in Visual Basic .NET. Instead of having the compiler implement late binding, you must explicitly implement late binding in code by using reflection. 
 
Handing Unmanaged Code
Visual C# .NET permits you to write unmanaged code. In unmanaged code, you can do things such as declare and operate on pointers, perform conversions between pointers and integral types, and take the address of variables. In a sense, writing unmanaged code is much like writing Visual C code in a Visual C# .NET program.
 
Because code that is written by using an unmanaged context cannot be verified to be safe, it is run only when the code is fully trusted. Do not use unmanaged context to try to write Visual C code in Visual C# .NET. Unmanaged code must be clearly marked with the modifier unsafe so that developers cannot use unmanaged features accidentally, and the execution engine works to make sure that unmanaged code cannot be run in a non-trusted environment. The scope of the unmanaged context extends from the parameter list to the end of the function, so pointers can also be used in the parameter list.
In Visual Basic .NET, you cannot write unmanaged code.
 
Keywords
The following table lists the keywords that Visual Basic .NET and Visual C# .NET use in several categories. This information can also be found in the Visual Studio .NET online documentation.
Purpose                 Visual Basic .NET             Visual C# .NET
OOP  
Indicates a class       Public Class Class1           public class Class1
constructor                Public Sub New(..)         {
                              MyBase.New                 public Class1(..)
                              …                          {
                           End Sub                          …
                           …                             }
                        End Class                        ….
                        Note: You have to call the    }
                        base class constructor        Note: The call to the base class
                        explicitly in VB .NET.        constructor (base()) is generated        
                                                      automatically by the compiler
                                                      in Visual C# .NET if you do not
                                                      include constructor initializers. 
 
Indicates a class       Protected Overrides Sub       public class Class1
destructor              Finalize()                    {
Note: The Destructor       m_Gadget = Nothing            public ~Class1()
or Finalize method         m_Gear = Nothing              {
is called by garbage       MyBase.Finalize()             ….
collection.             End Sub                         }
                                                      }
 
Declares a class        Class                         class
     
Indicates class         Public Class A                public class A : B
inheritance                   Inherits B              {
                           …                             …
                        End Class                     }
 
Indicates that the      MustInherit                   abstract
class can only be
inherited and cannot
be instantiated  
 
Indicates that the      NotInheritable                sealed
class cannot be
inherited  
 
Calls your own          MyClass                       None
implementation of the
method instead of an
overridden method
in the derived class   
 
Refers to a base class MyBase                        base
from the derived class 
 
Declares a type-safe    Delegate                      delegate
reference to a class
method     
 
Indicates that the      Overrides                     override
method or the
property overrides
the implementation
in its base class         
 
Indicates that these    MustOverride(in MustInherit   abstract (in abstract
methods have no         class)                        class)
implementation and
must be implemented
in derived classes     
 
Indicates that the      NotOverridable                sealed
method or the           Note: By default, methods 
property cannot be      are not overridable.   
overridden in
derived classes  
 
Indicates that the      Overridable                   virtual
 
method or the
property can be
overridden in an
inheriting class 
 
Overloads a             Overloads                     None. Define functions with
procedure, a function,                                same name but different signatures.
or a method     
 
Specifies that a        WithEvents                    No specific keyword
variable can contain
an object whose
events you want to
handle     
 
Specifies the events    Handles (Event procedures     n/a
for which an event      can still be associated 
procedure will be       with a WithEvents variable
called                  by naming pattern.)
 
Evaluates an object     With objExpr                  n/a
expression one time        <.member>
to access multiple         <.member>
members                 End With
 
Refers to the           Me                            This
current object   
 
Declares an             Enum                          Enum
enumerated type            …
                        End Enum   
 
Declares an interface   Interface                     interface
 
Implements an interface Implements                    class C1 : I1
 
Indicates an indexer    Default Property              public string this[int index]
                                                      {
                                                       get {return List[index];}
                                                       set {List[index]=value;}
                                                      }
Class Access Modifiers       
Indicates that          Public                        public
the modifier is
accessible outside
the project or the
assembly   
 
Indicates that the      Friend                        internal
modifier is
accessible inside
the assembly only      
 
Indicates that the      Private                       private
modifier is
accessible only in
the project (for
nested classes, in
the enclosing class)   
 
Class Member Access Modifiers      
Indicates that the      Public                        public
modifier is
accessible outside
the class and
the project
 
Indicates that the      Friend                        internal
modifier is
accessible outside
the class, but in
the project      
 
Indicates that the      Private                       private
modifier is only
accessible in a
class or a module
 
Indicates that the      Protected                     protected
modifier is
accessible only to
current and derived
classes    
 
Indicates the union     Protected Friend              protected internal
of Protected and
Friend or Internal     
 
Indicates that the      Shared                        static
members are shared
across all instances   
 
Miscellaneous Lifetime             
Preserves the local     Static                        n/a
variables for the
procedure  
Other      
Calls the Windows API   Declare statement             use Platform Invoke
 
Indicates a comment     ', Rem                        //, /* */ for miltine comments,
                                                      /// for XML comments
 
Indicates a constant    Const                         Const, readonly
 
Creates a new object    New, CreateObject             new
 
Declares a function     Sub                           void
or a method with no
return value     
 
Declares that an        n/a                           volatile
object can be
modified
asynchronously   
 
Declares a variable     Private, Public, Friend,      declarators (keywords include
                        Protected, Static,            user-defined types and                                                  Shared, Dim                   built-in types)
 
 
Declares a variable     Option Explicit               None (All variables
explicitly                                            must be declared before use)
 
Declares and raises     Event, RaiseEvent             event
an event   
 
Declares a structure    Structure                     struct
                           …
                        End Structure    
 
Defines a default       Default                       by using indexers
property         
 
Declares a null object Nothing                       null
 
Declares a namespace    Namespace                     Namespace
                           …                          {
                        End Namespace                    …
                                                      }
 
Indicates namespace     Imports                       using
usage
 
Retrieves a character  GetChar Function              [ ]
from a string          
 
Returns the address     AddressOf (For class          delegate
of a function           members, this operator
                        returns a reference
                        to a function in the
                        form of a delegate
                        instance)  
 
Tests for a null        Obj Is Nothing                obj == null
object     
 
Tests for a database    IsDbNull                      n/a
null expression  
 
Threads primitives      SyncLock                      lock