ArgumentException:方法参数不兼容

时间:2016-01-05 19:37:40

标签: c# reflection unity3d delegates mono

我正在尝试为特效制作一个事件系统

我有一个静态类的函数,允许我将任何基本事件处理程序链接到任何基本事件,无论每个对象的类,只要它们具有所需的函数

这是函数

(在具有多个非常有用的泛型函数的公共静态类中

    public static bool eventLinker<T,Y>(T listener, Y speaker, string eventName, string eventHandler)
{
    EventInfo eInfo = typeof(Y).GetEvent(eventName);
    MethodInfo evHandler = typeof(T).GetMethod(eventHandler, new Type[2] {typeof(object), typeof(EventArgs)});
    Type handlerType = eInfo.EventHandlerType;

    if(eInfo != null && evHandler != null && handlerType != null)
    {

        Delegate d = Delegate.CreateDelegate(handlerType, speaker, evHandler);
        eInfo.AddEventHandler(listener,d);

        return true;
    }
    return false;
}

这应该适用于任何有课程的班级 公共事件EventHandler SomethingHappened;

public void nameOfTheFunctionThatTriggerTheEvent()
{
    EventHandler handler = SomethingHappened;
    if(handler != null)
    {
        handler(this, EventArgs.Empty);
    }

}

任何有

的班级
public void HandleEvent(object sender, EventArgs e)
{
    Debug.Log("Something happened to " + sender);
}

我总是在Delegate.CreateDelegate

中收到此错误
  

ArgumentException:方法参数不兼容   System.Delegate.CreateDelegate(System.Type类型,System.Object   firstArgument,System.Reflection.MethodInfo方法,布尔值   throwOnBindFailure)(at   /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Delegate.cs:263)   System.Delegate.CreateDelegate(System.Type类型,System.Object   firstArgument,System.Reflection.MethodInfo方法)(at   /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Delegate.cs:276)   FunctionExt.eventLinker [Effect,Test](.Effect listener,.Test speaker,   System.String eventName,System.String eventHandler)(at   Assets / _C#/ FunctionExt.cs:41)GameUpdate.Awake()(at   资产/ _C#/ GameUpdate.cs:84)

我无法在任何地方找到解决方案。

3 个答案:

答案 0 :(得分:2)

如果您使用的是Unity(IF), 我遇到了同样的问题,我要做的就是制作另一个导致该问题的元素的对象,然后从引起问题的对象的检查器中复制组件,然后将其粘贴到您创建的新对象中,它奏效了,Idk为什么会这样做,但是只要确保您从检查器中复制并粘贴每个组件,然后将其粘贴到新组件即可。

答案 1 :(得分:1)

首先,AddEventHandler需要将target作为第一个参数,并且您传递的是不正确的侦听器。

接下来,当您创建委托时,您应该使用另一个方法签名CreateDelegate,因为第一个参数将从处理程序调用传递(请参阅代码handler(this, EventArgs.Empty);)。

整个代码:

public static bool eventLinker<T, Y>(T listener, Y speaker, string eventName, string eventHandler)
{
    EventInfo eInfo = typeof(Y).GetEvent(eventName);
    MethodInfo evHandler = typeof(T).GetMethod(eventHandler, new Type[2] { typeof(object), typeof(EventArgs) });
    Type handlerType = eInfo.EventHandlerType;

    if (eInfo != null && evHandler != null && handlerType != null)
    {
        Delegate d = Delegate.CreateDelegate(handlerType, listener, eventHandler);
        eInfo.AddEventHandler(speaker, d);

        return true;
    }
    return false;
}

或者您可以使用替代更通用和安全的代码来检查create delegate上存在的事件处理程序:

public static bool eventLinker<T, Y>(T listener, Y speaker, string eventName, string eventHandler)
{
    EventInfo eInfo = typeof(Y).GetEvent(eventName);
    Type handlerType = eInfo.EventHandlerType;

    if (eInfo != null && handlerType != null)
    {
        Delegate d = Delegate.CreateDelegate(handlerType, listener, eventHandler, false, false);
        if (d != null)
        {
            eInfo.AddEventHandler(speaker, d);
            return true;
        }
    }
    return false;
}

最后一个示例没有硬编码处理程序参数typeof(object), typeof(EventArgs),然后可以处理具有自定义事件类型的方案。

答案 2 :(得分:0)

您的错误就在行中:

Delegate d = Delegate.CreateDelegate(handlerType, speaker, evHandler);
eInfo.AddEventHandler(listener,d);

AddEventHandler想知道您要绑定event的{​​{1}}。所以它必须是:

delegate

我试了一下。我花了一段时间才弄明白。