C#, .Net and Azure

Reflection (1/5) - Overview & metadata

2012/12/27

This is the first post in a series. All posts are short excerpts from my Reflection paper.

First of all we need to understand the concept of Reflection and how it is integrated in .Net.

In .Net, each class automatically derives from System.Object. System.Object contains a set of methods that are thus accessible on each and every instance of any type of class. These methods are: ToString, Equals, GetHashCode and GetType

The last method can be seen as the entry point for Reflection. GetType (and its return type ‘Type’) provide information about a given type. This information is instance independent. It contains all sorts of properties and methods, such as: IsAbstract, IsPublic, the list of interfaces the type implements, the set of members, etc.

With that information, we already know a great deal about a given type and we can drill even deeper, as the same level of information exists for fields, properties, events, methods, parameters of methods and even the assembly itself.

.Net stores information about each type in the assembly, giving the programmer access to that information during runtime.

Essentially, the code is able to look at itself while it is running. In further parts of this series, we will see how the code is even able to modify itself based on that information.

Using tools to look at sourcecode

The term Reflector is closely named and is very useful, when working with .Net code. It is a tool (similar to ILSpy, dotPeek, justDecompile and many more) that allows the user to take a look at the code of any given .Net assembly/executable. Unlike native code, it is very easy to disassemble managed code from its executable form back to its natural code.

Since the .Net framework stores so much information about the code, it is very easy to reconstruct it after it has been compiled. It is even possible to compile C# code and create a VB.Net project from the executable, since the code is stored in the MSIL (Microsoft Intermediate Language) inside the assembly, that is common to all languages of the .Net framework.

If a project has been compiled in release mode, the names of private members will be obscured and mostly named ‘variable1’, ‘_variable1’ or similar, however the code is still readable.

If one would go about to look at the generated code for a property such as:

public int MyProperty { get; set; }

one would notice, that C# properties do not exist as such in the final code. They are merely syntactical sugar and are compiled to:

[CompilerGenerated]
private int <MyProperty>_BackingField;
void set_MyProperty(int i)
{
    <MyProperty>_BackingField = i;
}
void get_MyProperty()
{
    return <MyProperty>_BackingField;
}

Note the < and > in the variable name. This is not allowed for any of your own variables (this is also why it’s not possible to access the backing field from code).

However, having a property MyProperty in a class will result in compile errors when trying to add methods with the described signatures and names (int get_MyProperty and void set_MyProperty).

Type ‘TestClass’ already reserves a member called ‘set_MyProperty’ with the same parameter types

Conclusion

Here we can already see a first glimpse of what is possible with reflection: The compiler prevents the user from creating certain methods, since he knows that he will have to generate them in the future based of the property.

In further posts, we will see many more examples, where using Reflection results in a lot less code that needs to be written.

While the code that needs to be written will be slightly more complicated, the overall application will be improve, because their will be less redundant code and a lot of information can be expressed easily using reflection.

tagged as C#, Reflection,