Предполагая, что methodName
является статическим методом QueryWindow
, это должно работать:
private static void RegisterEvent(object targetObject, string eventName, string methodName)
{
var eventInfo = targetObject.GetType().GetEvent(eventName);
var method = eventInfo.EventHandlerType.GetMethod("Invoke");
var types = method.GetParameters().Select(param => param.ParameterType);
var methodInfo = typeof(QueryWindow).GetMethod(methodName, new[] { typeof(object) });
// replaced typeof(void) by null
var dynamicMethod = new DynamicMethod(eventInfo.EventHandlerType.Name, null, types.ToArray(), typeof(QueryWindow));
ILGenerator ilGenerator = dynamicMethod.GetILGenerator(256);
// Using Ldarg_0 to pass the sender to methodName ; Ldarg_1 to pass the event args
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.EmitCall(OpCodes.Call, methodInfo, null);
// Added return
ilGenerator.Emit(OpCodes.Ret);
// Removed parameter definition (implicit from DynamicMethod constructor)
// Removed the target argument
var methodDelegate = dynamicMethod.CreateDelegate(eventInfo.EventHandlerType);
eventInfo.AddEventHandler(targetObject, methodDelegate);
}
Редактировать:
Поскольку вы можете использовать .NET 3.5, вы должны создать дерево выражений. Вот еще одно решение:
public class QueryWindow
{
public void RegisterEvent(object targetObject, string eventName, string methodName)
{
var eventInfo = targetObject.GetType().GetEvent(eventName);
var sender = Expression.Parameter(typeof (object), "sender");
var e = Expression.Parameter(typeof (EventArgs), "e");
var body = Expression.Call(Expression.Constant(this), methodName, null, e);
var lambda = Expression.Lambda(eventInfo.EventHandlerType, body, sender, e);
eventInfo.AddEventHandler(targetObject, lambda.Compile() );
}
public void OnEvent(object o)
{
Console.WriteLine(o);
}
}
Обратите внимание, что метод OnEvent
больше не является статическим. Я также предполагаю, что события, на которые вы пытаетесь подписаться, являются событиями, которые следуют соглашениям .NET (отправитель + аргументы событий). Таким образом, мы можем использовать контравариантность и всегда передавать лямбду типа:
(object sender, EventArgs e) => { /* */ }