Blog

  • Home /
  • Blog /
  • CreateDelegate – An Exercise in Using Expressions

CreateDelegate – An Exercise in Using Expressions

July 30, 2010

In a previous blog post I showed a basic example of how to use the Delegate.CreateDelegate() method as an alternative to the slow MethodInfo.Invoke() for dynamically invoking a method of a class at runtime. The only downside of using CreateDelegate is that its not strongly typed. This is usually not a problem when the signature of the method that must be invoked is known at compile as is the case in the example shown in the blog post mentioned earlier.

Here we’re simply able to cast the result to the requested delegate type. But what if a generic method must be invoked for which the type parameters can vary at runtime? You can still use the CreateDelegate method, but you can’t cast the result to a strongly typed delegate type. This means that in order to invoke the created delegate, the DynamicInvoke method must be called on the returned Delegate object. This has the nasty side effect that when the original method being called throws an exception, the DynamicInvoke method wraps the original exception in a TargetInvocationException.  

So in order to find a better way and also exercise my Expressions-fu, I tried to come up with a CreateDelegate extension method that can be used to a create a strongly typed delegate for a MethodInfo object.

Suppose we have to dynamically invoke a method with the following signature:

Given an instance of IDomainEvent and IEvent, using the CreateDelegate extension method that I’m about to show, we can dynamically invoke this method using the following code:

Here we determine a specific MethodInfo object for the Map method using the types of the event objects we have. Now here’s the code for the strongly typed CreateDelegate extension method.

var subject = new Subject();
var doSomething = (Func<string, string="">)
    Delegate.CreateDelegate(typeof(Func<string, string="">), subject, "DoSomething");
Console.WriteLine(doSomething("Hello Freggles"));</string,></string,>

I actually provided two CreateDelegate methods here, one for instance methods (the first one) and one for static methods ( the second one). The created delegates are cached in a dictionary because the call of lambda.Compile() seems to be quite expensive.

Now I have to warn you that, based on first preliminary measurements, this implementation probably isn’t going to outperform  Delegate.CreateDelegate(). In fact, if you’re interested have a look at this approach first as it seems much faster. I added some spike code to the Elegant Code repository for those who fancy to take a look.  

</t>

If you and your team want to learn more about how to write maintainable unit tests and get the most out of TDD practices, make sure to have look at our trainings and workshops or check out the books section. Feel free to reach out at infonull@nullprincipal-itnull.be.

Profile picture of Jan Van Ryswyck

Jan Van Ryswyck

Thank you for visiting my blog. I’m a professional software developer since Y2K. A blogger since Y2K+5. Provider of training and coaching in XP practices. Curator of the Awesome Talks list. Past organizer of the European Virtual ALT.NET meetings. Thinking and learning about all kinds of technologies since forever.

Comments

About

Thank you for visiting my website. I’m a professional software developer since Y2K. A blogger since Y2K+5. Author of Writing Maintainable Unit Tests. Provider of training and coaching in XP practices. Curator of the Awesome Talks list. Thinking and learning about all kinds of technologies since forever.

Contact information

(+32) 496 38 00 82

infonull@nullprincipal-itnull.be