如何从struct的实例方法创建一个开放的Delegate?

Mic*_*l B 5 c# delegates

我有一个带有私有方法的结构,我想调用它.由于我计划在性能关键部分执行此操作,因此我想缓存一个委托来执行操作.问题是我似乎无法使用Delegate.CreateDelegate绑定到它的方法.有问题的结构不是我的创建,用于与第三方库的交互.有问题的结构看起来像这样::

public struct A
{
     private int SomeMethod()
     {
        //body go here
     }
}
Run Code Online (Sandbox Code Playgroud)

以下代码将失败,并出现"绑定到目标方法的错误".

Delegate.CreateDelegate(typeof(Func<A,int>),typeof(A).GetMethod("SomeMethod",BindingFlags.Instance | BindingFlags.NonPublic));
Run Code Online (Sandbox Code Playgroud)

我知道我可以写一个表达式树来执行动作,但似乎很奇怪,我不能使用我的正常goto这些Delegate.CreateDelegate方法.

如果A是一个类,上面的代码工作得很好.这个问题只是因为A结构而产生的.MSDN文档对于CreateDelegate的这个重载是不正确的,因为它对非静态方法起作用.

Dr.*_*ice 10

有趣的问题.从这个错误报告中,看起来这可能是一个将在未来版本的.NET中修复的错误:http: //connect.microsoft.com/VisualStudio/feedback/details/574959/cannot-create-open-instance -delegate换值类型的方法,其中实施的安接口#细节

编辑:实际上,我认为这个错误报告是关于一个不同的问题,所以你看到的行为实际上可能不是一个错误.

从该错误报告中,我发现如果您将委托的第一个参数指定为通过引用传递,则可以解决该问题.以下是一个完整的工作示例:

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));
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑: Jon Skeet在这里的答案也讨论了这个问题.