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.
A delegate is a reference type variable that holds the reference to a method. The reference can be changed at runtime. Delegates are especially used for implementing events and the call-back methods. All delegates are implicitly derived from the System. Delegate class.
Namespace: System Assembly: System.Runtime.dll. Represents a delegate, which is a data structure that refers to a static method or to a class instance and an instance method of that class.
Delegates in C# NET object which points to a method that matches its specific signature. A delegate is a form of type-safe function pointer used by the Common Language Infrastructure. You create a delegate with the delegate keyword, followed by a return type and the signature of the methods that can be delegated to it.
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:
public struct A
{
private int _Value;
public int Value
{
get { return _Value; }
set { _Value = value; }
}
private int SomeMethod()
{
return _Value;
}
}
delegate int SomeMethodHandler(ref A instance);
class Program
{
static void Main(string[] args)
{
var method = typeof(A).GetMethod("SomeMethod", BindingFlags.Instance | BindingFlags.NonPublic);
SomeMethodHandler d = (SomeMethodHandler)Delegate.CreateDelegate(typeof(SomeMethodHandler), method);
A instance = new A();
instance.Value = 5;
Console.WriteLine(d(ref instance));
}
}
EDIT: Jon Skeet's answer here also discusses this issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With