I have a struct with a private method that I’d like to invoke. Since I plan to do this in a performance critical section, I’d like to cache a delegate to perform the action. The problem is I can’t seem to bind to its method with Delegate.CreateDelegate. The struct in question is not my creation and is used in interaction with a third party library.
The struct in question looks like this::
public struct A
{
private int SomeMethod()
{
//body go here
}
}
And the following code will fail with an “Error binding to target method”.
Delegate.CreateDelegate(typeof(Func<A,int>),typeof(A).GetMethod("SomeMethod",BindingFlags.Instance | BindingFlags.NonPublic));
I know I can write an expression tree to perform the action, but it seems odd that I can’t use my normal goto for these things the Delegate.CreateDelegate method.
The above code works just fine if A were a class. The issue only arises because A is a struct.
MSDN documentation is incorrect for this overload of CreateDelegate as it does work on non-static methods.
Interesting problem. From this bug report, it looks like this might be a bug that will be fixed in a future version of .NET:
http://connect.microsoft.com/VisualStudio/feedback/details/574959/cannot-create-open-instance-delegate-for-value-types-methods-which-implement-an-interface#details
EDIT: actually, I think this bug report is regarding a different issue, so the behavior you’re seeing may not actually be a bug.
From that bug report, I gleaned that there is a work-around if you specify the first argument of your delegate as being passed by reference. Below is a complete working example:
EDIT: Jon Skeet’s answer here also discusses this issue.