我想了解动态生成的事件处理程序,我有困难,试图重新这种简单的情况有点:C#不能动态生成这个简单的事件处理程序
public delegate void SomethingHappenedEventHandler(object sender, object args);
public event SomethingHappenedEventHandler SomethingHappened;
// This is the event handler that I want to create dynamically
public void DoSomething(object a, object b)
{
DoSomethingElse(a, b);
}
public void DoSomethingElse(object a, object b)
{
Console.WriteLine("Yay! " + a + " " + b);
}
我用反射器产生IL为DoSomething的方法,它给我:
.method public hidebysig instance void DoSomething(object a, object b) cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: ldarg.1
L_0002: ldarg.2
L_0003: call instance void MyNamespace::DoSomethingElse(object, object)
L_0008: ret
}
所以,我写了下面的代码,以动态生成和执行的方法相当于DoSomething的(...):
public void CreateDynamicHandler()
{
var eventInfo = GetType().GetEvent("SomethingHappened");
var eventHandlerType = eventInfo.EventHandlerType;
var dynamicMethod = new DynamicMethod("DynamicMethod", null, new[] { typeof(object), typeof(object) }, GetType());
var ilgen = dynamicMethod.GetILGenerator();
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Ldarg_1);
ilgen.Emit(OpCodes.Ldarg_2);
MethodInfo doSomethingElse = GetType().GetMethod("DoSomethingElse", new[] { typeof(object), typeof(object) });
ilgen.Emit(OpCodes.Call, doSomethingElse);
ilgen.Emit(OpCodes.Ret);
Delegate emitted = dynamicMethod.CreateDelegate(eventHandlerType);
emitted.DynamicInvoke("hello", "world");
}
但是,当我运行这个我得到一个InvalidProgramException:JIT编译器遇到了内部限制。
任何人都可以指出我出错的地方吗?
[编辑]正如几个人所评论的,如果我知道所有涉及的类型,整个IL代的事情是不必要的。我这样做的理由是,这是在运行时动态生成事件处理程序的第一步,我不知道涉及的所有类型。基本上我一直在http://msdn.microsoft.com/en-us/library/ms228976.aspx之后的例子中,被卡住了,然后试着将事情放松一个简单的例子,我可以工作。
您可以使用表达式来编译函数。这通常比使用Reflection更容易.Emit – CodesInChaos 2011-03-04 12:32:09
为什么你让你的“发射”变量是一个委托?使其与您的eventHandlerType和强制类型相同。然后你可以像调用普通而不是DynamicInvoke()那样调用它。如果这不是你的问题,哪一行会引发异常?该信息会有帮助。 – jonathanpeppers 2011-03-04 13:00:47
即使使用您的EDIT,仍然不太可能需要通过在运行时生成IL来动态生成方法。您仍然可以在运行时使用反射类型和方法并使用['MethodBase.Invoke()'](http://msdn.microsoft.com/zh-cn/library/a89hcwhh%28v=vs.85% 29.aspx)来调用它们,或者您可以使用['dynamic'](http://msdn.microsoft.com/en-us/library/dd264741.aspx)类型。 – Timwi 2011-03-04 20:53:19