我希望能够通过将事件的名称和操作取决于客户端代码来订阅任何对象的事件。我有以下代码
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);
事件发射时会导致无效的摄影。我知道这是一个棘手的,我可以简单地使用 =订阅,但是有人可以告诉我为什么我的代码崩溃吗?我想iLgenerator.emit有什么问题,任何建议?
您忘了在DynamicMethod
结束时返回。
var method = new DynamicMethod("method", typeof (void), handlerArgs);
var generator = method.GetILGenerator(256);
generator.EmitCall(OpCodes.Call, handler.Method, null);
generator.Emit(OpCodes.Ret); //every method must have a return statement
以及编译器为() => MessageBox.Show("hello")
lambda创建的类是私人的。[参考]
当您在public
类中使用public
static
方法时,它起作用。
var Polygons = new ObservableCollection<Polygon>(myList);
Polygons.Subscriber<NotifyCollectionChangedEventArgs>
("CollectionChanged",
() => MessageBox.Show("hello"), //must in a public class and a public static method
e => e.OldItems != null);