Category: Expression Trees

There is no doubt about it; out of all the programming languages I ever experimented with, C# has offered me the most streamlined positive development experience so far. It is a modern, ever-evolving language, which now that C# and the whole .NET framework is turning to open source, is guaranteed an even greater future. However, some core constructs commonly available in other languages, like intervals which I introduce an implementation of in this post, are missing. E.g., Ruby has had Ranges for quite some time.

A Range represents an interval—a set of values with a beginning and an end.

Straightforward, but due to the lack of support for generic calculations in C#, a hassle to implement. However, as introduced by Marc Gravell, with some runtime compilation trickery involving expression trees, far from out of reach. I’ve had an Interval class within my core library for quite some time, but just now refactored it to also support more complex intervals, e.g. an interval between two DateTime instances, which thus represents a TimeSpan.

Without further ado, an example of what using this looks like in practice.

As you might notice, the timeRepresentation interval has just one generic parameter (Interval<int>), whereas thisYear has two (Interval<DateTime, TimeSpan>). The less generic (one type parameter) class is a simple wrapper around the more generic base type which has two type parameters; the first denotes the type used to represent any position within the range, whereas the second type is used to represent differences between these positions. When these types are the same, the simplified wrapper can be used. Likewise, a TimeInterval wrapper can easily be created if you find Interval to be too verbose.

Worth noting here to understand how it works under the covers is the constructor which sets two public static fields used during operations when conversions to double are needed. Arguably, this could be improved by having a factory creating the intervals and using constructor injection instead.

Once you start incorporating the notion of an interval in your programming arsenal you will be amazed by the opportunities which present themselves where to use them! Some actual examples within my core library:

… but, there is one pesky little issue I have with them. By design, it’s really easy to introduce bugs using them. How often have you encountered a NullReferenceException because you didn’t check whether an event handler was null prior to calling it? As a more experienced developer you might choose one out of the following two options.

There might be a small cost of constantly having to call one extra function when the event is raised, but it solves the problem of having to do repeated null checks throughout the code while simultaneously solving the multi-threading issue.

public event EventHandler SomeEvent = delegate {};

The Aspect way

I prefer the second approach, and don’t see any reason why it shouldn’t be used by default, other than a smarter compiler which could take care of this in a ‘cleaner’ manner. That’s why over the weekend I’ve spent some time seeing how PostSharp could help solving this cross-cutting concern. I always love showing off the result prior to explaining how I got there. It’s usage is a one liner.

Adding this one attribute prevents you from having to worry about events throughout the entire namespace it applies to.

How does it work?

First of all, you will need PostSharp. That’s not necessarily a bad thing, because if you are fortunate enough to be allowed to use it, or you can simply decide for yourself to buy it, you will greatly appreciate it for more than just this one possible use case.

The InitializeEventHandlersAttribute is called an aspect which is applied on events. However, using a feature of PostSharp called ‘multicasting’, you are able to apply the attribute (MulticastAttribute) on higher level elements, allowing you to choose which one of the lower level elements the aspect should apply to. In the code above, the aspect is applied on an entire assembly, but the aspect knows it should only be applied to events, which is further narrowed down using the AttributeTargetTypes parameter to events within the namespace “Laevo”, and all sub-namespaces. In order to remind the developer that a certain part of his code is enhanced by an aspect, a visualization as follows is visible within Visual Studio.

The code is short enough to paste in its entirety now, but I’ll decompose it in a minute.

Create a new class, deriving from the relevant aspect class. Since I am creating an aspect which is applied on events, I used EventLevelAspect.

Choose on which part of the code your aspect will have effect. This is called an ‘advice’. Although my aspect is applied on events, the solution I used is to add an empty event handler to the events by default. This is something which can be done from the constructor. Therefore I had to use an OnMethodEntryAdvice in order to add this code to the beginning of every constructor.

Choosing a ‘pointcut’ is required to determine where the code needs to be added. We’ve already established it needs to be added to the start of methods by using OnMethodEntryAdvice, but we haven’t established which methods it needs to be applied to yet. By using a MethodPointcut, this task is delegated to a separate method of which you pass the name. In my case, this method doesn’t do much more than returning all the constructors of the current type.

We are nearly done, although there is one part of the code I skipped over which is quite interesting nonetheless. The OnMethodEntryAdvice calls the delegate _addEmptyEventHandler(), but where did this come from? Overriding RuntimeInitialize gives you the chance to initialize objects which the advice will require for the specific element the aspect applies to. Using reflection to analyze the passed EventInfo object, a suitable empty event handler can be constructed using Expression Trees. This is required since we don’t have the luxury of using an equivalent to ‘delegate {}’. Finally a simple delegate is created which can add the empty delegate to the event of any given instance.

Closed delegate: an instance is bound to the delegate along with the method. In practice this means when calling the delegate, it will always operate on the same instance.

Open delegate: not bound to a specific target object until invocation time. An instance on which the method should operate is passed as first argument during invocation.

For now, I will only discuss creating open instance delegates. These allow you to invoke an instance method, while passing a first argument, specifying the instance on which it should be invoked.

Divide your programs into methods that perform one identifiable task. Keep all of the operations in a method at the same level of abstraction. – Kent Beck’s Smalltalk Best Practice Patterns

In an attempt to better follow this principle, better known as the Single Level of Abstraction (SLAP) principle, I’ve split up the CreateDelegate method into two helper methods. One to create ‘simple’ delegates, and one to create open instance delegates. Later, an additional third method could be added to create closed static delegates.

By ‘simple’ delegates I mean delegates of which the signature matches that of MethodInfo. More particularly, the method has the same amount of arguments than the delegate.

By default, this method results in a simple CreateDelegate call. Instead of having to pass the delegate type as an argument a generic approach is used, eliminating the need to cast the returned delegate. When the options argument is set to CreateOptions.Downcasting, this method behaves like the CreateDowncastingDelegate method from my previous post. Downcasts from the delegate argument types and return type to the required types of the method are generated where needed.

The helper method to create open instance delegates looks as follows:

/// <summary>
/// Creates a delegate of a specified type that represents a method
/// which can be executed on an instance passed as parameter.
/// </summary>
/// <typeparam name = "TDelegate">
/// The type for the delegate. This delegate needs at least one (first) type parameter
/// denoting the type of the instance which will be passed.
/// E.g. Action<ExampleObject, object>,
/// where ExampleObject denotes the instance type and object denotes
/// the desired type of the first parameter of the method.
/// </typeparam>
/// <param name = "method">The MethodInfo describing the method of the instance type.</param>
/// <param name = "options">Options which specify what type of delegate should be created.</param>
public static TDelegate CreateOpenInstanceDelegate<TDelegate>(
MethodInfo method,
CreateOptions options = CreateOptions.None )
where TDelegate : class
{ ... }

The comments indicate clearly what TDelegate should look like. Of course, no instance can be passed, clearly specifying it needs to be specified in the delegate type. Furthermore, the passed MethodInfo is required to be an instance method. All these measures are meant to clarify this specific usage of CreateDelegate. Additionally, similar to passing CreateOptions.Downcasting to the other helper method, it allows you to break the variance safety of the ordinary CreateDelegate method.

Using reflection, .NET allows you to create delegates based on MethodInfo objects. Calling a delegate is a lot more performant than using Invoke as already discussed by Jon Skeet. His results showed a delegate invocation is 600 times as fast. Plenty of reason to go through the extra effort of creating and caching a delegate. However, in a real world scenario when adding behavior to an existing class by using reflection, you’ll quickly encounter several limitations when using CreateDelegate. This post shows you where, and how to easily work around them.

In my previous article I discussed covariance and contravariance. One of the limitations of CreateDelegate is it only allows you to create delegates according to those rules. This makes perfect sense, but isn’t always desirable in practical use cases.

How would you go about creating a delegate for any method which is attributed with CallThis when the exact type of the argument is unknown? You do know the method’s signature matches Action, and only the correct type will ever be passed to the delegate.

Can this downcast be generated at runtime? Yes, and the easiest approach seems to be by using expression trees. Instead of passing the type of the required delegate to create as an argument, I opted to use a generic approach. Its usage looks as follows:

I’m still not entirely satisfied with the name of the method. CreateDowncastingDelegate refers to the fact that downcasts are generated where necessary. Its usage looks more like an upcasted delegate however. If anyone can come up with a better name, be sure to let me know.

The entire source code can be found in the FCL Extension library. In there you can also find another method which will most likely be the subject of my next post.