Неясно, почему вы хотите создать этот метод динамически.Я не могу вспомнить ни одной ситуации, в которой вы не могли бы просто применить лямбду к событию:
public delegate void SomethingHappenedEventHandler(object sender, object args);
public event SomethingHappenedEventHandler SomethingHappened;
public void DoSomethingElse(object a, object b)
{
Console.WriteLine("Yay! " + a + " " + b);
}
// If the signature exactly matches the delegate, just use the method name
SomethingHappened += DoSomethingElse;
public void DoSomethingDifferent(object a)
{
Console.WriteLine("Yay! " + a);
}
// Otherwise, just use a lambda expression
SomethingHappened += (a, b) => DoSomethingDifferent(a);
При этом причина, по которой ваш код не работает, заключается в том, что DynamicMethod
генерирует толькостатические методы.Поэтому код IL недопустим, поскольку Ldarg_0
и Ldarg_1
загружают два параметра, но Ldarg_2
относится к несуществующему параметру.Если я изменю его следующим образом, он будет работать, как и следовало ожидать - теперь это статический метод с тремя параметрами, где первый параметр в основном this
:
public void CreateDynamicHandler()
{
var dynamicMethod = new DynamicMethod("DynamicMethod", null,
new[] { typeof(MyClass), typeof(object), typeof(object) }, typeof(MyClass));
var ilgen = dynamicMethod.GetILGenerator();
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Ldarg_1);
ilgen.Emit(OpCodes.Ldarg_2);
MethodInfo doSomethingElse = typeof(MyClass).GetMethod("DoSomethingElse",
new[] { typeof(object), typeof(object) });
ilgen.Emit(OpCodes.Call, doSomethingElse);
ilgen.Emit(OpCodes.Ret);
Delegate emitted = dynamicMethod.CreateDelegate(
typeof(Action<MyClass, string, string>));
emitted.DynamicInvoke(this, "Hello", "World");
}
Замените «MyClass
» на имя вашего класса.
Что касается EDIT вашего вопроса, вам не нужно генерировать динамический метод путем написания кода IL для динамического вызова метода во время выполнения.,Просто используйте Reflection, например:
public void DoSomething(object a, object b)
{
var method = GetType().GetMethod("DoSomethingElse", BindingFlags.Instance | BindingFlags.Public);
method.Invoke(this, new object[] { a, b });
}
или:
// Note “static”
public static void DoSomething(dynamic instance, object a, object b)
{
// This will call whatever “DoSomethingElse” method exists on the type
// that “instance” has *at run-time*
instance.DoSomethingElse(a, b);
}