我在使用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:游戏对象已正确分配,因此不为空
乔恩说的。
此外,如果您尝试进行一些黑客攻击(而不是生产级代码),这里有一些实用的建议:查看源代码(或使用 Reflector 或 dotPeek 等反汇编器),看看事件是如何调用的。
- 如果有调用它的方法,请使用反射调用该方法
-
否则,如果事件使用编译器生成的字段,请使用
Type.GetField
检索该字段(它将与事件具有相同的名称),然后调用GetValue
以获取实际委托-
如果委托类型是公共的,则强制转换值并调用
((MyDelegate)fieldValue)(arg1, arg2...)
-
否则,强制转换为
Delegate
并使用动态调用方法((Delegate)fieldValue).DynamicInvoke(new object[] { arg1, arg2 })
-
您正在尝试调用委托的 Invoke
方法,但使用的是Tester.Main
实例。这是错误的 - 因为Tester.Main
实例不是相应委托的实例。
如果你试图真正提出gameVideoLoader
事件,那就另当别论了......以及无论如何你不应该做的事情。事件的目的是允许客户端订阅和取消订阅处理程序 - 对象本身应该负责引发事件。您可能能够找到用于实现事件的基础字段,获取该字段的值并调用委托 - 但我强烈建议不要这样做。在这一点上,你基本上违背了事件的设计。