Look Under the Hood For C# .NET Developers

In this article I provide a few under the code concepts of the C# programming language and .NET Framework. In my previous article I explained a few best practices of C# .NET and rely I am very much excited by getting comment and their constructive feedback. You can read it here.  And this inspiration leads me to write this article. Hope you will enjoy it. The code used in this article is compiled and run in windows platform with 64 bit operating system (Yes ! in my laptop). And when I have tested it I don't forget it to get output in release mode. So, let's start our journey of "behind the scene concepts".

  1. Code optimizer is much more clever than the programmer.

    Let me prove it practically. If we only initialize a variable and do not use it anywhere in our program code then the optimizer does not even consider it as a variable at the time of IL code generation. Have a glance at the following code. Here I have created three variables and assigned a value to it but have not used it anywhere in the program.

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Diagnostics;

    using System.IO;

    namespace Test

    {

       class Program

        {

           static void Main(string[] args)

            {

               int a = 100;

               int b = 200;

               String C = "Sourav";

     

            }

        }

    }

      
    And now let's see the IL code using the IL Disassembler.

    Code-Behind-in-Csharp-1.jpg

    Now I have made some changes in the code, nothing except those variable are now used as in the following:
     

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Diagnostics;

    using System.IO;

    namespace Test

    {

       class Program

        {

           static void Main(string[] args)

            {

               int a = 100;

               int b = 200;

               String C = "Sourav";

     

                a = a + 10;

                b = b + 10;

                C = C +"Kayal";

            }

        }

    }

    And here is the screen of the IL code. You can clearly see three variables have been created in our IL code. So, we can draw the conclusion that the ".NET code optimizer is smart enough to produce the most optimized IL code".

    Code-Behind-in-Csharp-2.jpg

  2. Who concatenates my string when I use the "+" operator for string concatenation?

    Dear friend, we developers very frequently use the "+" operator to concatenate two strings in our daily programming life. Have you ever thought about how the IL code is generated when we use the "+" operator to concatenate two strings?  Yes, I know you are thinking here that the "+" operator is overloaded and it concatenates two strings. Let's see that practically. See the following C# code:

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Diagnostics;

    using System.IO;

    namespace Test

    {

       class Program

        {

           static void Main(string[] args)

            {

               string name = "Sourav";

                name = name +"Kayal";

            }

        }

    }


    And here I have taken the IL Code apart:

    Code-Behind-in-Csharp-3.jpg
     
    We can see that the IL code uses the concat function to do the concatenation and it is clearly visible that the location of the Concat function is within the String class under the system namespace. If you are not interested in using the "+" operator then you can call this function directly as in the following code.
     

    classProgram

    {

       static void Main(string[] args)

        {

            String Name = System.String.Concat("Sourav","Kayal");

        }

    }

    And here also if you check the IL code then you can find that the same function is called in the IL code. Are you curious to know what happens in the case of StringBuilder? Please continue reading. 

    In the code below I have used StringBuilder to concatenate the strings.

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Diagnostics;

    using System.IO;

    namespace Test

    {

       class Program

        {

           static void Main(string[] args)

            {

               StringBuilder sb =new StringBuilder();

                sb.Append("Sourav");

            }

        }

    }
     
    And here is the corresponding IL code:

    Code-Behind-in-Csharp-4.jpg

     Here we can see that the append function is being called in the case of StringBuilder. And the location of StringBuilder is  System.Text.StringBuilder.
     

  3. Be careful when calling a function of any class.

    Let's see various ways to call a function and its impact on code performance. Look at the code below to call a function (member function of a class) using the class object.

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Diagnostics;

    using System.IO;

    namespace Test

    {

       public classSample

        {

           public void SomeMethod() { }

        }

       class Program

        {

           static void Main(string[] args)

            {

               Sample sample = new Sample();

                sample.SomeMethod();

            }

        }

    }
     
    And here is the IL code output:

    Code-Behind-in-Csharp-5.jpg

    We can see only one stack call has occured in the body of the main function. Do not understood? maxstack defines how much stack allocation is needed to execute this code. The maxstack value is 1 to call the function using the class object.

    Now, let us see the code below, I am doing the same operation in a different way.

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Diagnostics;

    using System.IO;

    namespace Test

    {

       public classSample

        {

           public void SomeMethod() { }

        }

       class Program

        {

           static void Main(string[] args)

            {

               new Sample().SomeMethod();

            }

        }

    }
     
    Here is the IL code of this code.

    Code-Behind-in-Csharp-6.jpg

    How, is it showing 8 maxstack, in other words 8 times big stack allocation?. And more stack allocation 

    means more time is required for execution.

    So dear friend, be careful when you are calling a function.
     

  4. How do various datatypes convert in IL code?

    At this point we will see how data types are converted in IL code. In a program, whatever data type (pre-defined) we define in our code is ultimately converted to a .NET Data Type. In theory, we studied that .NET Framework support many languages and ultimately all data types are converted to a .NET native data type. Let's see that in action.

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Diagnostics;

    using System.IO;

    namespace Test

    {

       class Program

        {

           static void Main(string[] args)

            {

               int a = 100;

               float f = 200;

               decimal d = 300m;

               double dou = 100.10;

               uint us = 10;

                a = a + 100;

                f = f + 100;

                d = d + 100;

                dou = dou + 10.10;

                us = us + 1;

            }

        }

    }

Here is the IL output:

Code-Behind-in-Csharp-7.jpg

It's clearly visible that all data types are converted to a .NET native data type.


Recommended Free Ebook
Similar Articles