c# - 是否可以编写一个类来隐藏添加 WeakEventManager 处理程序和传统处理程序之间的区别?

标签 c# events event-handling weakeventmanager

我有一个使用大量事件的 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);

关于c# - 是否可以编写一个类来隐藏添加 WeakEventManager 处理程序和传统处理程序之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40332448/

相关文章:

android - 屏幕打开时更新 Android Widget

javascript - 将变量值传递给 JavaScript 实时事件

jquery - 单击时使用 jQuery 拆分或连接文本

javascript - 使用 jQuery/Javascript 的 DOM 事件仅适用于 $().ready 或 window.onload

c# - 形成两个列表并集的最简单方法

c# - 我正在使用 OpenXML SDK 合并两个 Word 文档,但在将图像复制到标题中时得到损坏的文档

wpf - 手动输入日期时 DatePickerSelectedDateChanged 事件发生两次

c++ - 在 C++ 中作为 C 样式事件的事件处理程序的类成员

c# - .NET Xml 序列化 : Integer Element with Attribute?

C# 在计时器中添加和删除事件