如何从一个结构体的实例方法创建一个开放的委托? [英] How can I create an open Delegate from a struct's instance method?

查看:100
本文介绍了如何从一个结构体的实例方法创建一个开放的委托?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个我想要调用的私有方法的结构体。由于我计划在性能关键部分执行此操作,因此我希望缓存代理来执行该操作。问题是我似乎无法使用Delegate.CreateDelegate绑定到它的方法。所讨论的结构不是我的创建,并且用于与第三方库的交互。
该问题的结构看起来像这样::

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆