Latest Replies
Saturday
Jan032009

Strongly Typed Reflection in Lokad Shared

Express

System.Reflection.Express class from the Lokad Shared Libraries contains methods for retrieving reflection information through the Lambda expressions.

Currently you can use it to reflect:

  • Property
  • Field
  • Method
  • Constructor

Here's the use-case sample for method reflection options:

// reflecting method of current instance
// 'this.' is not necessary
Express.Method(() => this.GetHashCode());
// reflecting public method of some type
Express<object>.Method(o => o.GetHashCode());
// another way to reflect method
// arguments are ignored here
Express.Method(() => string.IsNullOrEmpty(null));

Reflection of fields, properties and constructors works exactly the same way.

The primary advantage of using helpers like this one is to avoid referencing members by their name (this is known to break on refactoring) and performing collection lookups.

Note, that this approach does not completely save you from some performance penalties of using reflection, since Lambda Expressions always have creation penalty (it is in the constructor).

Reflect

System.Reflection.Reflect does similar things as Express, yet the principles are slightly different:

  • We use delegates instead of expressions (although syntax is same), thus there is no initialization cost.
  • Internally IL parsing is used to retrieve the Member Info (instead of walking through the expression tree)

Here are the use cases currently supported:

var myVar = new
{
  Property = "Test"
};
// returns fieldInfo that reflects
// captured instance of myVar
// (FieldInfo.Name == 'myVar')
Reflect.Variable(() => myVar);
// retrieves MethodInfo to target the
// getter of the provided property
Reflect.Property(() => myVar.Property);

Some more information on the expression-based and IL-based strongly typed reflection could be found in this article: How to Find Out Variable or Parameter Name in C#?

ILHelper

There is additional code helper class called System.Reflection.ILHelper that is really useful as a quick IL parser.

Common usage scenario is to hit some breakpoint in the code, then fire up the Immediate Window (it allows you to execute and evaluate custom statments) in Visual Studio and type in something like:

ILHelper.Read(expression);

The output could look like:

[0]: {000 Code: ldarg.0, Operand: 0 (Int32)}
[1]: {001 Code: stloc.0, Operand: 0 (Int32)}
[2]: {002 Code: br.s, Operand: 0 (SByte)}
[3]: {004 Code: ldloc.0, Operand: 0 (Int32)}
[4]: {005 Code: ret, Operand: 0 (Int32)}

ILHelper is not compiled in the release code, since this is not a production-quality IL parser, but rather a development helper based on the excellent article by Sorin Serban and the code sample. However feel free to grab the ILHelper.cs from the source and use it as you may see fit.

I'd be interested to hear your thoughts about these helpers from the latest version of Lokad Shared Libraries.

« How to Target Multiple .NET Frameworks | Main | Efficient Development Must Be Ergonomic »