如何从一个结构体的实例方法创建一个开放的委托? [英] How can I create an open Delegate from a struct's instance method?
问题描述
该问题的结构看起来像这样::
public struct A
{
private int SomeMethod()
{
// body go here
}
}
以下代码将失败,并显示绑定到目标方法的错误。
Delegate.CreateDelegate (typeof(Func< A,int>),typeof(A).GetMethod(SomeMethod,BindingFlags.Instance | BindingFlags.NonPublic));
我知道我可以写一个表达式的树来执行这个动作,但是我可以'使用我的正常goto这些东西 Delegate.CreateDelegate
方法。
上面的代码工作正常,如果 A
是一个类。这个问题只是因为 A
是一个结构体。
对于CreateDelegate的这种重载,MSDN文档不正确,因为它在非静态方法上有效。
有趣的问题。从这个错误报告,看起来这可能是将来版本的.NET中修复的错误:
http://connect.microsoft.com/VisualStudio/feedback/详细信息/ 574959 / can not-create-open-instance-delegate-for-value-types-methods-which-implement-an-interface#details
编辑:实际上,我认为这个错误报告是针对一个不同的问题,所以你看到的行为可能不是一个错误。
从该错误报告中我收集如果您指定代理的第一个参数作为参考传递,那么有一个解决方法。以下是一个完整的工作示例:
public struct A
{
private int _Value;
public int Value
{
get {return _Value; }
set {_Value = value; }
}
private int SomeMethod()
{
return _Value;
}
}
委托int SomeMethodHandler(ref A instance);
类程序
{
static void Main(string [] args)
{
var method = typeof(A).GetMethod(SomeMethod ,BindingFlags.Instance | BindingFlags.NonPublic);
SomeMethodHandler d =(SomeMethodHandler)Delegate.CreateDelegate(typeof(SomeMethodHandler),方法);
A instance = new A();
instance.Value = 5;
Console.WriteLine(d(ref instance));
}
}
编辑: Jon Skeet在这里的回答也讨论了这个问题。
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:
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.
这篇关于如何从一个结构体的实例方法创建一个开放的委托?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!