0

我有 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:游戏对象已正确分配,因此它不为空

4

2 回答 2

2

乔恩说的。

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

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

    • 如果委托类型是公共的,则转换值并调用

      ((MyDelegate)fieldValue)(arg1, arg2...)

    • 否则,转换为Delegate并使用动态调用方法

      ((Delegate)fieldValue).DynamicInvoke(new object[] { arg1, arg2 })

于 2013-10-03T07:00:45.260 回答
1

您正在尝试调用委托的 Invoke方法,但在一个Tester.Main实例上。那是错误的——因为该Tester.Main实例不是适当委托的实例。

如果你真的想提出这个gameVideoLoader事件,那就是另一回事了……而且你不应该做的事情。事件的目的是允许客户端订阅和取消订阅处理程序 - 对象本身应该负责引发事件。您可能能够找到一个用于实现事件的基础字段,获取该字段的值并调用委托 - 但我强烈建议不要这样做。在这一点上,你基本上违背了事件的设计。

于 2013-10-03T05:49:30.023 回答