是否可以编写一个 class 来隐藏添加 WeakEventManager 处理程序和传统处理程序之间的区别?
Is it possible to write a class that hides the difference between adding WeakEventManager handlers and traditional ones?
我有一个使用大量事件的 C# (.NET 4.6.1) 项目。我很想将所有事件处理程序移动到新的 WeakEventManager 模式 - 以避免无休止地担心注销处理程序以避免内存泄漏。
但是我必须做很多性能测试,并且想要一种在两种方法之间轻松切换的方法。到目前为止,我一直在使用条件编译来按照 :
#if WeakEvents
WeakEventManager<EventSource,EArgs>.AddHandler(source, "TheEvent", handler);
#else
source.TheEvent += handler;
#endif
这行得通,但很乱。理想情况下,我想创建一个 class 来隐藏它。即创建一个 class 内部可以使用任何一种方法。然后我可以更改我所有的源以使用新的 class 附加处理程序并轻松切换(或者甚至在将来移动到一些新方法)。
但是我看不出如何写 class - 因为我不能将事件作为参数传递 - 而且 handler/name 必须进行一些反思这超出了我。
有简单的方法吗?
这是一种方法:
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);
我有一个使用大量事件的 C# (.NET 4.6.1) 项目。我很想将所有事件处理程序移动到新的 WeakEventManager 模式 - 以避免无休止地担心注销处理程序以避免内存泄漏。
但是我必须做很多性能测试,并且想要一种在两种方法之间轻松切换的方法。到目前为止,我一直在使用条件编译来按照 :
#if WeakEvents
WeakEventManager<EventSource,EArgs>.AddHandler(source, "TheEvent", handler);
#else
source.TheEvent += handler;
#endif
这行得通,但很乱。理想情况下,我想创建一个 class 来隐藏它。即创建一个 class 内部可以使用任何一种方法。然后我可以更改我所有的源以使用新的 class 附加处理程序并轻松切换(或者甚至在将来移动到一些新方法)。
但是我看不出如何写 class - 因为我不能将事件作为参数传递 - 而且 handler/name 必须进行一些反思这超出了我。
有简单的方法吗?
这是一种方法:
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);