PropertyChangedEventManager:AddHandler vs AddListener

Esk*_*rsø 6 c# wpf events inotifypropertychanged

如前所述这里PropertyChangedEventManager

提供WeakEventManager实现,以便您可以使用"弱事件侦听器"模式来附加PropertyChanged事件的侦听器.

订阅属性更改有两种方法:

void AddHandler (INotifyPropertyChanged source, EventHandler<PropertyChangedEventArgs> handler, string propertyName)
void AddListener (INotifyPropertyChanged source, IWeakEventListener listener, string propertyName)
Run Code Online (Sandbox Code Playgroud)

他们最终都调用了相同的方法:

private void AddListener(INotifyPropertyChanged source, string propertyName, IWeakEventListener listener, EventHandler<PropertyChangedEventArgs> handler)
Run Code Online (Sandbox Code Playgroud)

使用listenerhandler设置为null.

我需要使用强大的事件处理程序(即source.PropertyChange += handler;)更改一些代码以遵循弱模式.使用该AddHandler方法这是微不足道的.是否有任何理由AddListener要求(这需要我实施IWeakEventListener)?

如果我要编写新代码,那么选择其中一个的原因是什么?

Ora*_*ski 8

AddHandler(...
Run Code Online (Sandbox Code Playgroud)

只是 .Net 4.5 的一项功能,它可以简化常见情况下的代码。因此,如果满足要求,则是更好的选择。

在.Net4.5之前只有:

AddListener(...
Run Code Online (Sandbox Code Playgroud)

您可以在以下来源找到更多信息:

  1. 书籍 - .NET 4.5 简介

...不再需要创建自定义 WeakEventManager 或实现 IWeakEventListener...

  1. 博客文章 - 弱事件模式改进

在 WPF 4.5 RC 中,弱事件模式得到了改进。除了侦听器之外,WeakEventManager 还支持处理程序。处理程序的定义类似于事件处理程序,但我们的类不需要实现特定的接口。另外,由于没有维护硬引用,因此不可能出现内存泄漏。


边注:

根据我的经验,这些解决方案并不是万无一失的,如果您或您团队中的某人使用 lambda 表达式作为处理程序,您仍然可能会出现内存泄漏。

当使用 lambda 表达式时,编译器会生成匿名类作为目标(新生成的类包装 lambda 表达式)。GC 会立即收集对该类的弱引用。

这是托马斯·莱维斯克的解释

特殊情况:匿名方法处理程序如果您使用匿名方法(例如 lambda 表达式)订阅事件,请确保保留对处理程序的引用,否则它将很快被收集...

ps 我最终使用了与Thomas Levesque解决方案类似的方法,并且为了保护团队不使用 lambda 注册,我检查(通过反射)每个处理程序是否是匿名方法。如果是,我会抛出一个异常 - 因此开发人员立即知道这是不可接受的,并更改他们的代码。