Share via


Whats the diff? [Ari Weinstein]

Over the past couple of weeks, there have been a number of questions as to the best practices in coding.  A couple of question in this area were related to casting and aliases.

One example of casting questions that have come in is which is better:

double x = (double) 5; or double x = 5;

An example relating to aliases is what is the difference between int and Int32 in C#? How does String and string vary (big versus little s)?

 

The quick answer is that in all three of these situations, both options produce the same code.  While that is good information, better information is how to determine if this is really the case.  You only need 3 simple tools to do this kind of testing: notepad, csc (if using c#), and ildasm.

 

For example, lets find out exactly what happens when casting.  Fire up notepad, and create two files, CastTestA.cs, and CastTestB.cs.

 

In CastTestA.cs, put the following code:

class CastTestA{

    static void Main()

    {

        double x = (double)5;

    }

}

 

In CastTestB.cs, put the following code:

class CastTestB{

    static void Main()

    {

        double x = 5;

    }

}

Save the files, and open up the Visual Studio Command Prompt under Visual Studio in the Start menu.  Navigate to the location where CastTestA.cs, and CastTestB.cs are and type csc CastTestA.cs and hit enter, and then type csc CastTestB.cs and hit enter.  You will now have CastTestA.exe, and CastTestB.exe in that directory.

 

So far, this is all “Hello, World” style stuff.  What makes this interesting is the application ILDASM.exe which is a Microsoft Intermediate Language (MSIL) disassembler included in the .Net SDK.  ILDASM parses any .NET .exe or .dll and presents the contents of it in a human readable format.  What is useful about this is that you can see exactly what IL instructions have been compiled from your source code.   

 

To do this, run ILDASM CastTestA.exe.  ILDASM will open with the name of your executable (CastTestA.exe), and as children in a treeview will be listed: Manifest and CastTestA.  Expand CastTestA and double click on Main : void(), which is the main method in the CastTestA class in the CastTestA.exe.  You will find the following IL code:

.method private hidebysig static void Main() cil managed

{

  .entrypoint

  // Code size 12 (0xc)

  .maxstack 1

  .locals init (float64 V_0)

  IL_0000: nop

  IL_0001: ldc.r8 5.

  IL_000a: stloc.0

  IL_000b: ret

} // end of method CastTestA::Main

Now, do the same with CastTestB.exe, you will get the following:

.method private hidebysig static void Main() cil managed

{

  .entrypoint

  // Code size 12 (0xc)

  .maxstack 1

  .locals init (float64 V_0)

  IL_0000: nop

  IL_0001: ldc.r8 5.

  IL_000a: stloc.0

  IL_000b: ret

} // end of method CastTestB::Main

Now you can compare the IL of the two methods.  Turns out they are identical, which means there is no difference between the different code.  In case you are curious, a list of IL instructions and what they do is available at https://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemreflectionemitopcodesmemberstopic.asp.  If you go through the IL and use this list, you can see exactly what operations every method in your code executes.

Try doing this again and compare String and string, int and Int32.  You will see that in both cases either option will give you the same IL, which means it’s the same exact executable. 

At this point, since we know that two different source codes produce the same IL, the only criteria for choosing one over the other should be whichever you feel more comfortable with.  For example, some people prefer to be conscious of what is occurring in their code and they tend to opt for the more exact option of writing out the cast, while others find source code without the cast more readable.  My only suggestions are: be consistent, and use whichever method you are most comfortable with.  Happy Coding!