Большинство событий ничего не возвращают - на самом деле вы утверждаете , что у него нет возвращаемого типа.Затем вы объявляете свой пользовательский метод (handler
) как возвращающий int
и пытаетесь связать его с делегатом, который не возвращает int.Это не сработает.
Также;ваш стек недопустим для возврата целого числа, так как вы «выталкиваете» результат.
т.е. я создал тест с
public event EventHandler SomeEvent;
и привязал его к нему;тогда вот:
Delegate dEmitted = handler.CreateDelegate(tDelegate);
вы обнаружите, что tDelegate
- это EventHandler
.Это не соответствует handler
, что возвращает int
.
Re the stack (комментарии);рассмотрим:
ilgen.Emit(OpCodes.Ldfld, counterFieldInfo); <=== should be ldsfld, by the way
ilgen.Emit(OpCodes.Ldc_I4, 1); // stack is now [counter] [1]
ilgen.Emit(OpCodes.Add); // stack is now [counter + 1]
ilgen.Emit(OpCodes.Pop); // stack is now empty
ilgen.Emit(OpCodes.Ret); // return
Вы загрузили два значения, сложили их, отбросили результат , а затем вернули.Но вы не вернули int
, который, как вы утверждаете, - это не выполнит проверку IL.
При изменении:
var handler =
new DynamicMethod("CompletedHandler",
null,
GetDelegateParameterTypes(tDelegate),
obj.GetType());
и:
ilgen.Emit(OpCodes.Ldsfld, counterFieldInfo);
ilgen.Emit(OpCodes.Ldc_I4_1);
ilgen.Emit(OpCodes.Add);
ilgen.Emit(OpCodes.Stsfld, counterFieldInfo);
ilgen.Emit(OpCodes.Ret);
тогда это может работать так, как вы намереваетесь.
Также;это проще:
Delegate dEmitted = handler.CreateDelegate(tDelegate);
eventInfo.AddEventHandler(obj, dEmitted);