Sunday, August 21, 2011

Open Instance Delegate for Generic Interface Methods

Ran into a snag when developing the latest abstraction for Sasa. The problem is distilled to its simplest form in this Stack Overflow question.

In summary, while the CLR supports open instance delegates to interface methods, and supports delegates to generic interface methods, it does not seem to support the composition of the two, ie. an open instance delegate to a generic interface method.

The following trivial example fails when creating the delegate with a NotSupportedException:
interface IFoo
{
  void Bar<T>(T j);
}
class Foo : IFoo
{
  public void Bar<T>(T j)
  {
  }
}
static void Main(string[] args)
{
  var bar = typeof(IFoo).GetMethod("Bar")
                        .MakeGenericMethod(typeof(int));
  var x = Delegate.CreateDelegate(typeof(Action<IFoo, int>),
                                  null, bar);
}

However, the CLR does support open instance delegates to generic class methods. For some reason interfaces are singled out here, and it's not clear why.

If I'm doing something wrong, please let me know!

Edit: I submitted a bug to Microsoft Connect, since this now looks like a legit bug.

Edit 2: MS acknowledged the limitation, but said it wouldn't be solved in the current version of .NET. As I explain in that bug, this limitation just doesn't seem to make sense, but it must be due to the internals that don't reuse the existing CLR dispatching logic.

No comments: