Article Image

Events and Expressions

I ran into a scenario recently where I had a C# Action (That is, void params, and void return), and needed to get it to execute when an event was triggered. Any event. With any number of parameters.

The way I solved this problem is using the LINQ Compiled Expression Trees. These little things are useful when you need to write a lambda/closure, and don't necessarily know what paramater types, or calls, will be passed in beforehand.

The Problem

Here, fundamentally, is what I was trying to solve:

public static void AddHandler(object instance, EventInfo eventInfo, Action action)
    eventInfo.AddEventHandler (instance, action); //Fit square square peg into round hole

The problem here is that I want to bind an action to an event, but don't know what the event delegate type is.

Why do this

In my case, it was part of a helper method for my UI library. I wanted someone to be able to bind to an event on a widget, but without knowing the exact parameters that event took ahead of time. This was purely sugar-coating.

Expressions to the Rescue

I ended up solving this by compiling an expression during runtime that takes the exact parameters of the event, and then wrapping the call to the Action.

Here's the code:

public static class AnonymousAction
    public static Delegate WrapDelegate(Action action, Type targetType)
        var invoke = targetType.GetMethod ("Invoke");
        if (invoke == null)
            throw new ArgumentException ("ofType must be delegate");

        var parameters = invoke.GetParameters ();
        var expressionParams = new ParameterExpression[parameters.Length];
        for (int i=0; i<parameters.Length; ++i)
            expressionParams [i] = Expression.Parameter (parameters [i].ParameterType);

        var call = Expression.Call (
            typeof(Action).GetMethod ("Invoke")

        return Expression.Lambda (targetType, call, expressionParams).Compile ();

public class MyReceiver
    public event Action<MyReceiver, int> OnAction;

    public void Do()
        OnAction (this, 22);

public class Test
    public void Run()
        Action onAction = () => {
            Console.WriteLine ("Did something");

        var receiver = new MyReceiver ();
        var evt = receiver.GetType ().GetEvent ("OnAction");
        evt.AddEventHandler (receiver, AnonymousAction.WrapDelegate (onAction, evt.EventHandlerType));

        receiver.Do ();
static void Main()
    var t = new Test ();
    t.Run ();
Blog Logo

Christopher LaPointe



Chris LaPointe

Another site of Code

Back to Overview