C# or VB.NET - What Difference Does It Make?

We have often considered here the question which programming language would be more advantageous for RPA in general or for UiPath in particular. Today I would take a look at this topic from a technical side. Normally we work in RPA environments in the business in the Microsoft Windows world. dotNET as an execution and programming environment is very closely related to this operating system, and to UiPath itself. In the UiPath Studio C# and VBdotNET are offered here as standard.

Once we have coded a sequence, this is translated by the dotNET into an intermediate code. The language used for this is called Intermediate Language (IL). That means, no matter what programming language we use, an intermediate code is always created. How does that look?

The Comparison

The following is an example comparison between C# and VBdotNET. To follow the example download the dotNET 6.0 SDK here. Unpack the zip file and add the path to your PATH environment variable. Download intermediate language disassembler ILDASM here.

C# VB.NET
dotnet new console --language "C#"
  --output myAppCSharp
dotnet new console --language VB
  --output myAppVB
cd myAppCSharp
cd myAppVB
Content of Program.cs
Console.WriteLine("Hello, World!");
Content of Program.vb
Imports System
Module Program
    Sub Main(args As String())
        Console.WriteLine("Hello World!")
    End Sub
End Module
dotnet build
dotnet build
cd bin\Debug\net6.0
cd bin\Debug\net6.0
ildasm myAppCSharp.dll
  /out=myAppCSharp.dll.il
ildasm myAppVB.dll
  /out=myAppVB.dll.il

Compare now both files: myAppCSharp.dll.il with myAppVB.dll.il to see the differences. Here a part:

// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi beforefieldinit Program
       extends [System.Runtime]System.Object
{
  .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) 
  .method private hidebysig static void  '<Main>$'(string[] args) cil managed
  {
    .entrypoint
    // Code size       12 (0xc)

    .maxstack  8
    IL_0000:  ldstr      "Hello, World!"
    IL_0005:  call       void [System.Console]System.Console::WriteLine(string)
    IL_000a:  nop
    IL_000b:  ret
  } // end of method Program::'<Main>$'

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       8 (0x8)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [System.Runtime]System.Object::.ctor()
    IL_0006:  nop
    IL_0007:  ret
  } // end of method Program::.ctor

} // end of class Program

// =============================================================
// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi sealed myAppVB.Program
       extends [System.Runtime]System.Object
{
  .custom instance void [Microsoft.VisualBasic.Core]Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute::.ctor() = ( 01 00 00 00 ) 
  .method public static void  Main(string[] args) cil managed
  {
    .entrypoint
    .custom instance void [System.Runtime]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
    // Code size       13 (0xd)
    .maxstack  8
    IL_0000:  nop
    IL_0001:  ldstr      "Hello World!"
    IL_0006:  call       void [System.Console]System.Console::WriteLine(string)
    IL_000b:  nop
    IL_000c:  ret
  } // end of method Program::Main

} // end of class myAppVB.Program

// =============================================================

The main routine, which we have created, is identical in content, but the frame is different.

Conclusion

We can assume that what we code in our programming language produces always, after translation into the IL, the same or similar IL code. From this perspective, the choice of programming language is irrelevant. Thus we can make the choice of programming language according to other criteria.

More about integration scenarios of other programming languages can be found here.

4 Likes