C# MethodInfo.Invoke TargetException

C# MethodInfo.Invoke TargetException,c#,xna,system.reflection,methodinfo,C#,Xna,System.reflection,Methodinfo,我对System.Reflection有一个问题,当我调用MethodInfo.Invoke方法时,它向我提供了TargetException异常,该异常表示:对象与目标不匹配,代码如下: object[] parms = new object[] { path }; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); Type gameType = null; foreach (Assembly asm in a

我对System.Reflection有一个问题,当我调用MethodInfo.Invoke方法时,它向我提供了TargetException异常,该异常表示:对象与目标不匹配,代码如下:

object[] parms = new object[] { path };

Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
Type gameType = null;

foreach (Assembly asm in assemblies)
{
    string asmName = asm.GetName().Name;

    if (asmName == "Tester")
    {
        gameType = asm.GetType("Tester.Main");
        break;
    }
}

var game = Convert.ChangeType(GameInstance, gameType);
Type delegateType = game.GetType().GetEvent("gameVideoLoader").EventHandlerType;

MethodInfo method = delegateType.GetMethod("Invoke");
method.Invoke(game,  parms); // Here the exception
有什么想法吗? PS:游戏对象已正确分配,因此它不是空的

您试图调用代理的
Invoke
方法,但在
Tester.Main
实例上。这是错误的-因为
Tester.Main
实例不是相应委托的实例

如果您试图实际引发
gameVideoLoader
事件,那么这是另一回事。。。还有一些你无论如何都不应该做的事。事件的目的是允许客户端订阅和取消订阅处理程序-对象本身应该负责引发事件。您可以找到一个用于实现事件的底层字段,获取该字段的值并调用委托,但我强烈建议不要这样做。此时,您基本上违反了事件的设计。

您试图调用委托的
Invoke
方法,但是在
Tester.Main
实例上。这是错误的-因为
Tester.Main
实例不是相应委托的实例

如果您试图实际引发
gameVideoLoader
事件,那么这是另一回事。。。还有一些你无论如何都不应该做的事。事件的目的是允许客户端订阅和取消订阅处理程序-对象本身应该负责引发事件。您可以找到一个用于实现事件的底层字段,获取该字段的值并调用委托,但我强烈建议不要这样做。在这一点上,你基本上违背了事件的设计。

乔恩说的话

此外,如果您试图进行一些黑客攻击(而不是生产级代码),这里有一些实用的建议:查看源代码(或使用反汇编程序,如Reflector或dotPeek),看看事件是如何调用的

  • 如果有方法调用它,请使用反射来调用该方法
  • 否则,如果事件使用编译器生成的字段,请使用
    Type.GetField
    检索该字段(它将与事件同名),然后调用
    GetValue
    获取实际的委托

    • 如果委托类型为public,则强制转换该值并调用

      ((MyDelegate)字段值)(arg1、arg2…)

    • 否则,强制转换为委托,并使用动态调用方法

      ((委托)字段值).DynamicInvoke(新对象[]{arg1,arg2})

    • 乔恩说的话

      此外,如果您试图进行一些黑客攻击(而不是生产级代码),这里有一些实用的建议:查看源代码(或使用反汇编程序,如Reflector或dotPeek),看看事件是如何调用的

      • 如果有方法调用它,请使用反射来调用该方法
      • 否则,如果事件使用编译器生成的字段,请使用
        Type.GetField
        检索该字段(它将与事件同名),然后调用
        GetValue
        获取实际的委托

        • 如果委托类型为public,则强制转换该值并调用

          ((MyDelegate)字段值)(arg1、arg2…)

        • 否则,强制转换为委托,并使用动态调用方法

          ((委托)字段值).DynamicInvoke(新对象[]{arg1,arg2})


      我已经完成了您刚才所说的,现在我可以调用该方法,但出现了一个问题,他给了我另一个错误,我试图通过代理避免这个错误:
      public Video ShowVideo(string videoPath){Contract.Requires(videoPath!=null,“参数'Video'不能为null!”;Video Video Video=new Video(videoPath,false);video.Size=gameWindow.Size;video.Owner=videoBox;videoBox.Visible=true;video.Play();return video;}
      @thomassqall:这是代码,不是错误。您还没有告诉我们您遇到了什么错误。但是,您试图做的事情违反了事件的设计,我强烈建议您不要这样做。很抱歉,我正在工作,在我写答案的时候,他们(谁与我一起工作)由于搜索了我的问题,所以我在完成回答之前关闭了笔记本电脑,我将尝试再次编写XDI我已经完成了您刚才所说的,现在我可以调用该方法,但出现了一个问题,他告诉我另一个错误,我正试图避免与代表一起出现:
      public Video ShowVideo(string videoPath){Contract.Requires(videoPath!=null,“参数‘video’不能为null!”;video video=new video(videoPath,false);video.Size=gameWindow.Size;video.Owner=videoBox;videoBox.Visible=true;video.Play();return video;}
      @thomassqall:这是代码,不是错误。您还没有告诉我们您遇到了什么错误。但是,您试图做的事情违反了事件的设计,我强烈建议您不要这样做。很抱歉,我正在工作,在我写答案的时候,他们(谁与我一起工作)由于搜索了我的问题,所以我在完成回答之前关闭了笔记本电脑,我将尝试再次编写XD