我有一个集合
private ObservableCollection<Contact> _contacts;
在我班级的构造函数中,我创建它
_contacts = new ObservableCollection<Contact>();
我有方法来添加和删除我的集合中的项目。我想跟踪我的集合中实现IPropertyChanged接口的实体的更改,以便我订阅他们的PropertyChanged事件。
public void AddContact(Contact contact)
{
((INotifyPropertyChanged)contact).PropertyChanged += new PropertyChangedEventHandler(Contact_PropertyChanged);
_contacts.Add(contact);
}
public void AddContact(int index, Contact contact)
{
((INotifyPropertyChanged)contact).PropertyChanged += new PropertyChangedEventHandler(Contact_PropertyChanged);
_contacts.Insert(index, contact);
}
当我从集合中删除实体时,我取消订阅PropertyChanged事件。我被告知这是为了让实体被垃圾收集而不会造成内存问题。
public void RemoveContact(Contact contact)
{
((INotifyPropertyChanged)contact).PropertyChanged -= Contact_PropertyChanged;
_contacts.Remove(contact);
}
所以,我希望这一切都很好。现在,我需要在我的一个方法中清除集合。我的第一个想法是打电话给_contacts.Clear()
。然后我想知道这是否会释放这些事件订阅?我需要创建自己的清晰方法吗?像这样:
public void ClearContacts()
{
foreach(Contact contact in _contacts)
{
this.RemoveContact(contact);
}
}
我希望这里的一位.NET C#专家可以为我解决这个问题,或者告诉我我做错了什么。
答案 0 :(得分:4)
Clear()不会删除事件处理程序。 (另请注意,调用Clear()不会像Add()和Remove()那样触发CollectionChanged事件。)
答案 1 :(得分:1)
您可以为CollectionChanged
的{{1}}事件设置一个处理程序,这样可以在删除项目事件处理程序时取消它们,并且当您执行{{1但问题是ObservableCollection
上的Clear
集合将为空。
所以同意@Michael,要做你想做的事,你必须实现自己的Clear方法,也许作为一种扩展方法:
e.OldItems
在clear函数中,您可以在调用常规Clear()
函数之前迭代项目并清除事件处理程序。
答案 2 :(得分:0)
Clear()
不会发布这些活动订阅。
最好是你自己的清除方法迭代删除事件处理程序的集合,然后调用集合上的Clear()
。
执行此操作的原因是,在内部,Remove()
遍历集合,而不是为每个项目调用Remove()
,以便查找要删除的项目的索引,并且性能可能会受到影响如果集合中有大量项目。
答案 3 :(得分:0)
以下是Reflector的代码:
protected override void ClearItems()
{
this.CheckReentrancy();
base.ClearItems();
this.OnPropertyChanged("Count");
this.OnPropertyChanged("Item[]");
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
检查以确保其中一个事件处理程序未在循环中调用它,调用基本Collection
的{{1}}函数,通知订阅者属性已更改,最后通知订阅者该集合已更改。
在任何时候都没有清除任何一个事件处理程序。