Common Intermediate Language

Types, Classes and Properties

Types

Or classes.  There is probably one thing that will catch you out (well not really if you understand your compiler!) and that is in C# the compiler will go ahead and create a default constructor for you if you don't specify one, obviously when you are coding MSIL you've skipped that stage and are at a level where the bits aren't so generous - you will need to create your own default constructor.

Let's start off with a sample constructor that takes 2 string args, and then assigns those string to private fields named _firstName and _lastName.

.assembly extern mscorlib { }

.assembly Org.GBarnett 
{
	.ver 1:0:0:0
}

.module Org.GBarnett.dll

.class public Org.GBarnett.Person extends [mscorlib]System.Object
{
	.field private string _firstName
	.field private string _lastName
	
	.method public instance void .ctor() cil managed
	{
		.maxstack 8
		
		ldarg.0
		call instance void [mscorlib]System.Object::.ctor()
		
		ldarg.0
		ldarg.1
		stfld string Org.GBarnett.Person::_firstName 
		
		ldarg.0
		ldarg.2
		stfld string Org.GBarnett.Person::_lastName
		
		ret
	}
	
}

Every reference type in .NET derives from System.Object, however, in a high level language like C# and VB.NET this is done taken for granted, you don't explicitly do this -rather the C# or VB.NET compiler generates the appropriate output to reflect this.

Its fairly clear to see that the class is public, and that it has two fields of type string with the names mentioned before.

Now the interesting bit.  The first thing we do is load the objects this pointer onto the stack, then we call the constructor of the base type System.Object.

The next bits are pretty straight forward, we load each constructor parameter then store that parameter to its associated field.  Here is the Person class in C# we have so far replicated.

namespace Org.GBarnett
{
    public class Person
    {

        private string _firstName;
        private string _lastName;

        public Person(string firstName, string lastName)
        {
            _firstName = firstName;
            _lastName = lastName;
        }

    }
}

Properties

Hopefully you will be aware of the fact that properties in C# and VB.NET are actually represented by get_Xxx and set_Xxx methods by the respective compilers - if you're not then you are now!

So, when browsing the MSIL look for the get_Xxx and set_Xxx methods and not properties.  Btw Xxx refers to the property name, e.g. if I declare a read only property called FirstName then I would expect only to see a get_FirstName() method implementation in the MSIL.  I'm yet to really figure out whether I like properties or not, yes they are very handy but they are just another facade of the respective high level compilers - I want to know what the heck I'm actually creating and that becomes increasingly harder as the high level compilers take on more of the grunt work.

As I started writing this, and as I branched off to have a dig at properties I suddenly remembered  a feature in C# 3.0 that enraged me - smart properties.  Smart properties allow you to omit the body of a get and set for a property and even allow you to not define a corresponding field for that property...oh no! the compiler would do that for you - in my opinion this is just wrong.

Note:  smart properties are only available if you want to allow read and write access, you cannot have just one.

Anyway...

As you might of guessed a method in the case of for example the get_FirstName() is simply a case of loading the this instance of the Person object then pushing the _firstName string onto the stack then popping it off the stack and returning it. 

	.method public string get_FirstName() 
	{
		.maxstack 1
		
		.localsinit([0] string myRandom)
		
		ldarg.0
		
		ldfld string Org.GBarnett.Person::_firstName
		stloc.0
		ldloc.0
		
		ret
	}

I think it may be nice to in the next part take C# 3.0 apart and look at the internals of features like LINQ (especially expression trees), smart properties, object initializers and so on - the C# 3.0 compiler introduces more than ever before language constructs that appear very different than what you write in your C# or VB.NET.

You might also like...

Comments

About the author

Granville Barnettt United Kingdom

My name is Granville Barnett I have been a programmer now for quite some time mainly focusing on .NET technologies (C#), C++ and general research (algorithms, compilers etc)

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Theory is when you know something, but it doesn't work. Practice is when something works, but you don't know why. Programmers combine theory and practice: Nothing works and they don't know why.”