我有一个c#。NET 4.6.1)项目,该项目使用了大量事件。我想把所有的事件处理程序都移到新的WeakEventManager模式中——以避免无休止地担心取消注册处理程序以避免内存泄漏。
然而,我必须做大量的性能测试,并希望有一种方法可以轻松地在这两种方法之间切换。到目前为止,我一直在使用条件编译来实现这一点,如下所示:
#if WeakEvents
WeakEventManager<EventSource,EArgs>.AddHandler(source, "TheEvent", handler);
#else
source.TheEvent += handler;
#endif
这是有效的,但是很混乱。理想情况下,我想创建一个类来隐藏它。我创建了一个在内部可以使用任意一种方法的类。然后,我可以更改所有的源代码,以附加带有新类的处理程序,并轻松切换(甚至在将来移动到一些新方法)。
然而,我看不出如何编写该类-因为我不能将事件作为参数传递-并且必须有一些反射处理程序/名称,这超出了我的范围。
有简单的方法吗?
可以这样做:
static class EventHelper {
public static void Subscribe<TSource, TEventArgs>(TSource source, Expression<Func<TSource, EventHandler<TEventArgs>>> eventRef, EventHandler<TEventArgs> handler) where TEventArgs : EventArgs {
if (source == null)
throw new ArgumentNullException(nameof(source));
var memberExp = eventRef.Body as MemberExpression;
if (memberExp == null)
throw new ArgumentException("eventRef should be member access expression");
var eventName = memberExp.Member.Name;
#if WeakEvents
WeakEventManager<TSource, TEventArgs>.AddHandler(source, eventName, handler);
#else
// some reflection here to get to the event
var ev = source.GetType().GetEvent(eventName);
if (ev == null)
throw new ArgumentException($"There is no event with name {eventName} on type {source.GetType()}");
ev.AddMethod.Invoke(source, new object[] { handler });
#endif
}
}
用法很简单:
// second parameter is event reference
EventHelper.Subscribe(source, s => s.TheEvent, Handler);