Feeds:
Posts
Comments

In this post I’ll explore the MSIL generated for delegates and events when a project is compiled in Visual C# or any other language that target the .NET platform. This is my fourth post on exploring MSIL – Microsoft Intermediate Language.

Here are the links for my last three posts.

The lies of the C# compiler : It explores the MSIL equivalent of the C# accessors like protected, internal etc.

Exploring MSIL – Static and Instance Methods : It explores the difference in the MSIL generated for static and instance methods.

Exploring MSIL – Properties : It explores the generated MSIL for properties of a class.

As in the last posts, I’ll create a project with a class – Traffic light that contains the event SignalChanged. This event uses the delegate SignalChangedDelegate that encapsulates the methods that can be called once the event is triggered. Here goes the code.

public delegate void SignalChangedDelegate(string newSignal);

class TrafficLight
{
public event SignalChangedDelegate SignalChanged;
}

Now let us start by looking at the MSIL generated generated for the delegate – SignalChangedDelegate.delegate_msil.jpg

The delegate, SignalChangedDelegate, is actually a class that extends the class MulticastDelegate. The constructor, .ctor, takes 2 arguments – an object and a native int. Apart from the constructor there are three other methods -

1. BeginInvoke() method takes a string , a AsyncCallback and an object as arguments and returns an IAsyncResult.

2. EndInvoke() method takes an IAsyncResult and returns a void.

3. Invoke() method takes a string and returns void.

And here is the MSIL for the class TrafficLight that defines the event SignalChanged.event_msil1.jpg

The points to note are

1. A private field of the type of the SignalChangedDelegate is generated. The name of the field is same as that of the event which is shown by an inverted green triangle at the bottom of the image.

2. Two additional methods – add_SignalChanged and remove_SignalChanged are also generated and both of them take the SignalChangedDelegate as argument. Actually these are the methods that are called once listeners add or remove themselves for the SignalChanged event.

3. The event SignalChanged is also present which is as it is in the source code.

In the next post I am directly diving into the MSIL instructions and I’ll start with the example that every one starts with – The Hello World Program.

This is my third post on MSIL – Microsoft Intermediate Language – which is generated by the Visual C# compiler once the code is compiled. In this post I’ll take a look at the intermediate language generated for the properties of a class.

Here are my last two posts on MSIL.

The lies of the C# compiler : It explores the MSIL equivalent of the C# accessors like protected, internal etc.

Exploring MSIL – Static and Instance Methods : It explores the difference in the MSIL generated for static and instance methods.

I’ll create create a class BankAccount and add the properties CustomerName and Balance. CustomerName gives both read and write access while Balance is only read-only. The class members have been kept on minimum to focus on the MSIL generated for a property. Here is the code.

public class BankAccount
{
private string customerName;
private float balance;

public BankAccount(string name, float bal)
{
this.customerName = name;
this.balance = bal;
}

public string CustomerName
{
get { return customerName; }
set { customerName = value; } // both read and write access
}

public float Balance
{
get { return balance; } // read-only
}
}

And here is the intermediate language that is generated once the project is compiled.

properties_msil.jpg

The following points are worth observing.

1. Apart from generating the properties, the get_xxx and set_xxx methods have also been generated.

2. The get_xxx method is generated for the get accessor and the set_xxx method is generated for the set acessors in the property.

3. The get_xxx method returns a value of the same type as the field that is encapsulated by the property. For example, get_Balance() returns a float that is of the same type as the field balance.

4. The set_xxx method takes an argument and returns void. Again the type of the argument is same as the field that is encapsulated by the property.

Now let us have a closer look at the intermediate language generated for the property – CustomerName and it’s get and set accessors.

.property instance string CustomerName()
{
.get instance string BankAccount::get_CustomerName()
.set instance void BankAccount::set_CustomerName(string)
} // end of property BankAccount::CustomerName

The property, CustomerName, is an instance one and the field that it encapsulates is a string. It provides both read and write access. In case this property had encapsulated a static field, the word instance would had been missing and NOT replaced by static.

.method public hidebysig specialname instance string
get_CustomerName() cil managed
{
// Code size 12 (0xc)
.maxstack 1
.locals init ([0] string CS$1$0000)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld string BankAccount::customerName
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
} // end of method BankAccount::get_CustomerName

The get acessor of the property is actually an instance method that returns a string. I’ll explain the IL instructions in another post.

.method public hidebysig specialname instance void
set_CustomerName(string ‘value’) cil managed
{
// Code size 9 (0×9)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: stfld string BankAccount::customerName
IL_0008: ret
} // end of method BankAccount::set_CustomerName

The set acessor of the property is also an instance method that takes a string argument – value.

I believe this post gives a little more insight into the MSIL generated for the properties.

Last week I wrote my first post on MSIL – The lies of the C# compiler. It explores the MSIL equivalent of the C# accessors like protected, internal etc. In this post I’ll look into the difference in the MSIL for static and instance methods.

What are instance methods? The methods that can be accessed only through an object of the class are called instance methods. On the other hand static methods do not need an object to be accessed. They can be directly accessed through the class.

I’ll create a class – Test and add a static and a dynamic method. Here goes the code.

class Test
{
public void InstanceMethod()
{
// the instance method
}

public static void StaticMethod()
{
// the static method
}
}

Now let me show you the MSIL that is generated on compiling the solution.

.method public hidebysig instance void InstanceMethod() cil managed
{
// Code size 2 (0×2)
.maxstack 8
IL_0000: nop
IL_0001: ret
} // end of method Test::InstanceMethod

.method public hidebysig static void StaticMethod() cil managed
{
// Code size 2 (0×2)
.maxstack 8
IL_0000: nop
IL_0001: ret
} // end of method Test::StaticMethod

As is clear from the MSIL the InstanceMethod() is explicitly marked with the keyword instance in the generated intermediate language. The static method is anyhow marked as static in the source code.

Any non-static method is by default marked as instance by the C# compiler and can be seen in the generated intermediate language.

Here is the link to my next post : Exploring MSIL – Properties

Do you think it’s only humans who lie? I am talking of the false picture that the compiler paints of the C# programming language. Well in a way these ‘lies’ saves us from the crude details that are at work underneath. But at the same time they keep us ignorant of the internal details. In this post I’ll explore the accessors in C# language and look at their equivalent in the MSIL.
I’ll assume you have done some programming in one of the modern programming languages like Java or C# and you understand what is object oriented programming. I have used C# for writing the program. To begin with I’ll create a project – a class library in this case, add a class – BankAccount, add fields with different accessors and finally compile the project. And to catch the ‘lies’, I’ll open the generated assembly in the Ildasm.exe tool that is shipped with the .NET Framework.

Here is the code for the class that I have create. Remember the only logic that guides the choice of accessor for the fields is to include all of them so that we can look at the MSIL in one shot.

class BankAccount
{
private string customerName;

internal float balance;

protected char accountType;

protected internal bool hasCheckbook;

public int accountNumber;
}
And here is the MSIL that can be seen by opening the generated assembly in Ildasm.exe tool. Let us observe the accessors carefully.

accessor_msil.jpg

You will be surprised to find that there is nothing called protected or internal in the MSIL. Protected is actually family and internal is assembly. Protected internal is actually famorassem.

This post is the beginning of my series on MSIL and I expect to catch a lot of those compiler ‘lies’ on the way. This is the link to my next post: Exploring MSIL – Static and Instance Methods

While going through my blog stats today, I found something called ‘Referrers’ that is the pages from which people clicked links to get to my blog. I found just one entry – http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=2179898&SiteID=7

If you missed the essence, my blog – How to draw a custom border around a form or control? – is on MSDN forum! Great!

« Newer Posts - Older Posts »