2
我希望能夠通過傳遞事件的名稱和Action依賴於客戶端代碼來訂閱任何對象的任何事件。我有以下代碼上面的代碼使DynamicMethod調用其他方法
public static class EventSubscriber
{
public static object Subscriber<TEventArgs>(
this object obj,
string eventName,
Action handler,
Func<TEventArgs, bool> canExecute)
{
var eventInfo = obj.GetType().
GetEvent(eventName);
if (eventInfo == null)
throw new ArgumentException("Event name provided does not exist", nameof(eventName));
var handlerArgs = eventInfo.EventHandlerType.
GetMethod("Invoke").
GetParameters()
.Select(p => p.ParameterType).ToArray();
var method = new DynamicMethod("method", typeof (void), handlerArgs);
var generator = method.GetILGenerator(256);
generator.EmitCall(OpCodes.Call, handler.Method, null);
eventInfo.
AddEventHandler(
obj,
method.CreateDelegate(eventInfo.EventHandlerType));
return obj;
}
}
用法:
var Polygons = new ObservableCollection<Polygon>(myList);
Polygons.Subscriber<NotifyCollectionChangedEventArgs>
("CollectionChanged",
() => MessageBox.Show("hello"),
e => e.OldItems != null);
它會導致當InvalidProgramException事件觸發。 我知道這是一個棘手的問題,我可以簡單地使用+ =訂閱,但有人可以告訴我爲什麼我的代碼崩潰? 我想ILGenerator.Emit有什麼問題,有什麼建議嗎?