Click here to Skip to main content
15,867,488 members
Articles / Programming Languages / C# 4.0

How does it work in C#? - Part 1

Rate me:
Please Sign up or sign in to vote.
4.79/5 (78 votes)
20 Nov 2012CPOL7 min read 206.2K   2.5K   246   83
How does var, auto implemented properties and += or -= of events work in C# programming language.

Contents

  • Introduction
  • How does it work?
    • var and details
    • Auto-Implemented Properties
    • += and -= in Events
  • Limitations
  • Related Articles
  • History
  • References

Source code and Demo

Introduction

The C# language of the .NET(MSDN), has many features such as var to declare variable, implement the properties automatically and many more which makes life of a programmer easier. On the other hand, this abstraction creates a bit of confusion such as how does it work, how .Net implemented those stuffs in behind the scene. In this article, I will try to find out few of those stuff for example, var, Auto-Implemented properties and += or -= syntax used in Events.

How does it work?

In the following discussion, we will see how does var, auto-implemented properties and += and -= of Events work

var and details

In C#, it is possible to declare variable in few ways, implicit type declaration using var keyword is one of those. For example, it is possible to use var totalSalary =0; instead of int totalSalary =0;. As MSDN article suggested var is strongly typed but compiler determined the types. To explore it a bit more, I created a small class,

C#
namespace TestHarness
{
    public class VarExplorer
    {
        public Book ExploreVar()
        {
            var myBook = new Book() { Name = "What is out there?" };
            myBook.Name = "What is out there?";
            return myBook;
        }
    }
    public class Book
    {
        public string Name { get; set; }
    }
}

The above class is not doing much rather initialising an instance of type Book which contains a method named ExplorerVar. This method has variable declared using var. In the design time or coding or while writing code in the IDE, hover the mouse just above the keyword var then the compiler will determine the types of variable myBook. Please have a look the image below,


How_does_work_in_CSharp/VarAtDesignTime.PNG

Fig: var at design time

So it is clear that compiler determine the types at design time. Another question is what is happening at runtime? To test, I compiled the TestHarness project and grab the TestHarness.exe from the bin folder and drop into .Net Reflector program, using the help .Net Reflector the code I found out for ExploreVar method is as below,

C#
public Book ExploreVar() 
{
    Book <>g__initLocal0 = new Book {

        Name = "What is out there?"

    };
    Book myBook = <>g__initLocal0;
    myBook.Name = "What is out there?";
    return myBook; 
}

The above code clearly shows that compiler replace var keyword with appropriate type while building project as exe. From the above discussion, it is clear how does var work in C#.

Auto-Implemented Properties

In C# class declaration is pretty easy we declare a class using following syntax,

C#
public class Book 
{
       private string name;
       public string Name  
       {
            get {
                return name;
            }
            set {
                name = value;
            }
       }
}

It is really simple but from C# 3.0 it is more easier. We can declare Book class as below,

C#
public class Book
{ 

   public string Name { get; set; }

}

Now the question is what is the difference between that syntax used to declare a class. In reality there is nothing except compiler doing all the work for us. A Bit of background of class, the concept of the Encapsulation has been implemented in different way. First declaration of Book class, the encapsulation has done by introducing Properties which actually equivalent to Get and Set method. So it is not possible to directly access the private members of the class unless there is a Public Properties or Get/Set method.

Now for the second syntax of the Book declaration, compiler is doing all this encapsulation on behalf of a programmer. When decompile second version of Book using .Net Reflector, Compiler itself generates get and set methods for Name property and declare a variable name <Name>k__BackingField ( in here <Name> is actuall property name defined in Book class ),

So whole decompiled code for Name is as below,

C#
private string <name>k__BackingField;

public void set_Name(string value)
{
    this.<name>k__BackingField = value;
}

public string get_Name()
{
    return this.<name>k__BackingField;
}

From the above discussion clear that how compiler handle auto implemented properties. A bit more investigation at runtime, I created following code snippet to test the auto implemented properties stuff at run time,

C#
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;

    public class AutoImplementatedProperties
    {
        public IEnumerable<string> ExploreMembers(Person personObject)
        {
            return personObject.GetType().GetMembers().ToList<memberinfo>().Select(memberInfo => memberInfo.Name);
        }

        public IEnumerable<string> ExplorePrivateFields(Person personObject)
        {
            return personObject.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Select(fieldInfo => string.Format("{0,40}-->{1,20}", fieldInfo.Name, fieldInfo.GetValue(personObject).ToString()));
        }
        public Person CreateATestObject()
        {
            Person personObject = new Person()
            {
                Name = "M",
                Profession = "Coding"
            };
            return personObject;
        }
    }
    public class Person
    {
        public string Name { get; set; }
        public string Profession { get; set; }
    }
}

In the above class, ExploreMembers method will explore all the members of Person object and ExplorePrivateFields will explore all the private fields including their value of Person object. If we run the ExplorePrivateFields method then we can see it will display,

How_does_work_in_CSharp/OutputOfAutoImplementedProperties.PNG

Fig: Auto-implemented properties test result.

Above output and now if compare with Person instantiation code below,

C#
public Person CreateATestObject()
{
    Person personObject = new Person()
    {
        Name = "M",
        Profession = "Coding"
    };
    return personObject;
}

It is clear that How C# store Name and Profession property values at runtime.

+= and -= in Events

The definition of Event has been taken from MSDN. An event in C# is a way for a class to provide notifications to clients of that class when some interesting thing happens to an object.

The main point of this discussion is to discuss about, += (add) or -= (remove) syntax and how does it relates to the Event and delegate and also how does it work? Actually, the compiler translate += or -= into add or remove method in Layman’s terms. So to test the concept, I created small class (which is doing pretty much nothing),

C#
public class LogIt
{
    public delegate void LogHandler(string message);
    public event LogHandler Log;
    public Delegate[] GetList()
    {
        return Log.GetInvocationList();
    }
}

So the above class has a delegate name LogHandler and event named Log of type LogHandler. The consumer of this class is as below,

C#
public class AddRemoveHandlerOfEvent
{
    public LogIt InitialiseLogIt()
    {
        LogIt logItObject = new LogIt();
        logItObject.Log += new LogIt.LogHandler(Logger1);
        logItObject.Log += new LogIt.LogHandler(Logger2);
        logItObject.Log += new LogIt.LogHandler(Logger3);
        return logItObject;
    }

    public void Logger1(string s)
    {
        Console.WriteLine(s);
    }

    public void Logger2(string s)
    {
        Console.WriteLine(s);
    }

    public void Logger3(string s)
    {
        Console.WriteLine(s);
    }
}

So from the above consumer class we can see few methods such as Logger1, Logger2, Logger3 has been added to the Log of LogIt object. Now the question is where does these methods information stored or how does it works while use += or -= syntax. To answer the question again need to get help of .Net reflector. When we reflect the code we can see following code has generated by compiler for += or -=,

C#
public class LogIt
{
    // Nested Types
    public delegate void LogHandler(string message);
    // Fields
    private LogHandler Log;
    // Events
    public event LogHandler Log
    {
        add
        {
            LogHandler handler2;
            LogHandler log = this.Log;
            do
            {
                handler2 = log;
                LogHandler handler3 = (LogHandler) Delegate.Combine(handler2, value);
                log = Interlocked.CompareExchange<loghandler>(ref this.Log, handler3, handler2);
            }
            while (log != handler2);
        }
        remove
        {
            LogHandler handler2;
            LogHandler log = this.Log;
            do
            {
                handler2 = log;
                LogHandler handler3 = (LogHandler) Delegate.Remove(handler2, value);
                log = Interlocked.CompareExchange<loghandler>(ref this.Log, handler3, handler2);
            }
            while (log != handler2);
        }
    }
    // Methods
    public Delegate[] GetList()
    {
        return this.Log.GetInvocationList();
    }
}

There are two new stuffs which is add and remove, need to explore now does add and remove works, from add block one line of code give us all the clue which is,

C#
LogHandler handler3 = (LogHandler) Delegate.Combine(handler2, value);

and if we dig bit more with Combine method, we will find out something like below,

C#
public static Delegate Combine(Delegate a, Delegate b)
{
    if (a == null)
    {
      return b;
    }
    return a.CombineImpl(b);
}

The code block is from the Delegate class and also CombineImpl method called from Combine method is defined in the MulticastDelegate class.

The MulticastDelegate holds two variable

C#
private IntPtr _invocationCount; 
private object _invocationList; 

and this _invocationList is the main object which holds all the method signature assigned using += syntax. From the below images we can see how does _ invocationList used to store all the method signature as method pointer(IntPtr)

How_does_work_in_CSharp/ObjectAsInvocationList.PNG

Fig: _innvocationList of MulticastDelegate class

How_does_work_in_CSharp/ObjectHoldInvocationList.PNG

Fig: objArray at runtime.

How_does_work_in_CSharp/EventAtRuntimeResized.PNG

Fig: In depth view of the objArray to find out method information from _ innvocationList

To get a clear view of this, I created a small test program to test, how .Net store all the method inside the _invocationList. If we see the below code block of the CombineImpl method,

C#
public IEnumerable<string> GetInitialMethodPointer()
{
    return GetType().GetMethods().Select(methodInfo => string.Format("{0,40}-->{1,20}", methodInfo.Name, methodInfo.MethodHandle.Value.ToString()));
}

public IEnumerable<string> GetInvocationListFrom(LogIt logItObject)
{
    return logItObject.GetList().Select(delegateObject => string.Format("{0,40}-->{1,20}", delegateObject.Method.Name, delegateObject.Method.MethodHandle.Value.ToString()));
}
</string></string>

We can see, GetInitialMethodPointer method will show the initial methods pointer for Logger1, Logger2 and Logger3 and GetInvocationListFrom method will show what does _invocationList contains after using += operation to add method signneture. From the image below, it is clear that _invocationList contains exactly the same method pointer value we get from GetInitialMethodPointer.

How_does_work_in_CSharp/EventsOutput.PNG
Fig: Output of the method pointer store into _ innvocationList


The implementation of -= is also a bit of nice stuff to dissect. Following Call Stack will show how the remove calls from consumer code to all the way back into Delegate class to update _ invocationList list,
How_does_work_in_CSharp/RemoveEvents.PNG


Fig: Call Stack of Delete Operation


And if we look into the RemoveImpl method code then we can see it called another method named DeleteFromInvocationList as below,
How_does_work_in_CSharp/RemoveInitialCode.PNG

Fig: Inside of the RemoveImpl method


And code inside DeleteFromInvocationList will eventually update the _ invocationList list to update the current method signature after remove. Please see the following image,
How_does_work_in_CSharp/InsideOfDeleteOperation.PNG

Fig: Inside of DeleteFromInvocationList

So from the above discussion we have pretty good picture of how += and -= works for Events and Delegate.

If you interested detail about other features of the C# language, Expert C# 5.0 with the .NET 4.5 Framework might be useful.

Limitation

  • There is no discussion about how .Where, .Select extension methods work for a List.

Related Articles

History

Version 1.0

Reference

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Australia Australia

Comments and Discussions

 
AnswerRe: It was a good effort Pin
Mohammad A Rahman15-Nov-11 3:09
Mohammad A Rahman15-Nov-11 3:09 
QuestionNice article Pin
Sazalsiddiqui15-Nov-11 2:29
Sazalsiddiqui15-Nov-11 2:29 
AnswerRe: Nice article Pin
Mohammad A Rahman15-Nov-11 2:33
Mohammad A Rahman15-Nov-11 2:33 
GeneralMy Vote 5 Pin
Abinash Bishoyi14-Nov-11 4:37
Abinash Bishoyi14-Nov-11 4:37 
GeneralRe: My Vote 5 Pin
Mohammad A Rahman14-Nov-11 4:58
Mohammad A Rahman14-Nov-11 4:58 
QuestionMy Vote 5 Pin
feeza01258-Nov-11 23:05
feeza01258-Nov-11 23:05 
AnswerRe: My Vote 5 Pin
Mohammad A Rahman8-Nov-11 23:25
Mohammad A Rahman8-Nov-11 23:25 
Questionnice internal Pin
Ganesan Senthilvel26-Oct-11 19:00
Ganesan Senthilvel26-Oct-11 19:00 
AnswerRe: nice internal Pin
Mohammad A Rahman26-Oct-11 20:51
Mohammad A Rahman26-Oct-11 20:51 
QuestionMy vote of 5 -> Pin
kasunt26-Oct-11 6:13
kasunt26-Oct-11 6:13 
AnswerRe: My vote of 5 -> Pin
Mohammad A Rahman26-Oct-11 10:21
Mohammad A Rahman26-Oct-11 10:21 
GeneralMy vote of 5 Pin
ashutosh k. shukla24-Oct-11 22:16
ashutosh k. shukla24-Oct-11 22:16 
GeneralRe: My vote of 5 Pin
Mohammad A Rahman24-Oct-11 22:42
Mohammad A Rahman24-Oct-11 22:42 
GeneralMy vote of 5 Pin
Sergio Andrés Gutiérrez Rojas22-Oct-11 8:46
Sergio Andrés Gutiérrez Rojas22-Oct-11 8:46 
GeneralRe: My vote of 5 Pin
Mohammad A Rahman22-Oct-11 11:31
Mohammad A Rahman22-Oct-11 11:31 
QuestionThank you Pin
victorbos18-Oct-11 2:19
victorbos18-Oct-11 2:19 
AnswerRe: Thank you Pin
Mohammad A Rahman18-Oct-11 2:26
Mohammad A Rahman18-Oct-11 2:26 
GeneralMy vote of 4 Pin
Sumit P17-Oct-11 18:44
Sumit P17-Oct-11 18:44 
GeneralRe: My vote of 4 Pin
Mohammad A Rahman17-Oct-11 18:46
Mohammad A Rahman17-Oct-11 18:46 
GeneralMy vote of 5 Pin
gerkims17-Oct-11 12:24
gerkims17-Oct-11 12:24 
GeneralRe: My vote of 5 Pin
Mohammad A Rahman17-Oct-11 13:24
Mohammad A Rahman17-Oct-11 13:24 
GeneralMy vote of 5 Pin
hoernchenmeister10-Oct-11 23:58
hoernchenmeister10-Oct-11 23:58 
GeneralRe: My vote of 5 Pin
Mohammad A Rahman11-Oct-11 0:01
Mohammad A Rahman11-Oct-11 0:01 
QuestionToday I learnt something new about events. Pin
hvasilev10-Oct-11 23:27
hvasilev10-Oct-11 23:27 
AnswerRe: Today I learnt something new about events. Pin
Mohammad A Rahman10-Oct-11 23:30
Mohammad A Rahman10-Oct-11 23:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.