Delegate.CreateDelegate 以 lambda 作为方法会产生"method argument length mismatch"异常



我有问题,test1生产"系统。argumentException:方法参数长度不匹配",而test2和test3则良好。我需要使用反射订阅事件,如果我使用简单的方法,一切都有效,但是当我进入lambdas时,它会停止按预期工作。

调试所有lambdas显示它们是" void<> m__0(int32(",这是事件的正确类型,与" EventInfo.eventhandhandlertype"相同。

为什么失败?也许,如何解决问题?

c#是否将更多参数添加到lambda创建的方法中,例如test1?

::在此处完成代码:

public class A
{
    public void Test1()
    {
        var str = "aa";
        B.Subscribe(typeof(C), "myEvent", (int a) => { var any = str; }, null);
    }
    public void Test2()
    {
        B.Subscribe(typeof(C), "myEvent", (int a) => { var any = a; }, null);
    }
    public void Test3()
    {
        B.Subscribe<int>(typeof(C), "myEvent", callback, this);
    }
    public void callback(int a) { }
}
public static class B
{
    public static void Subscribe<T>(Type type, string eventName, Action<T> callback, object target)
    {
        var eventInfo = type.GetEvent(eventName, BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static);
        var handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, target, callback.Method);
        eventInfo.AddEventHandler(null, handler); 
    }
}
public sealed class C
{
    public static event Action<int> myEvent;
}

编辑:

显然是单声道错误。getInvocationList(([0]在上面的示例中将代表解决问题。

但要订阅事件会产生"系统。如果事件不是类型的操作,而是自定义代表:(如果类似" C"类,则会投掷,如果类似于上面的类,则可以通过(

(
public sealed class C
{
    public static event MyDel myEvent;
    public delegate void MyDel(int a);
}

这是不同的问题吗?编辑#2,事件期望MyDel类型,但获取操作INT32。我如何从Action<T>转换为MyDel或更高的eventInfo.EventHandlerType,因为我不知道可以发生哪种类型的事件。

实际上,经过进一步的调查,我注意到我的 target不好。

对于类在类中定义的方法,类实例为目标是可以的。对于lambdas,我认为它是空的,至少它可以与null一起使用,只要它不干扰创建lambda的方法中定义的局部变量。

so Action 使用Delegate.CreateDelegate中的callback.Target具有属性 TARGET 解决了问题。

lambda的目标实际上包含对类实例的引用,以及它触摸的所有本地变量(调试器显示(。

奇怪的是,它在最新的.net上起作用,也许是单声道和.net之间的略有区别。

相关内容

最新更新