修改集合时运行代码(添加或删除项目)

时间:2008-12-16 12:18:22

标签: .net collections

我有一个包含对象列表的类。修改列表时,在类中运行某些代码的最佳方法是什么?

class MyManagerClass
{
    ArrayList list = new ArrayList(); // will likely be a different collection class
    private OnItemAddedToList(object o)
    {
        // how to call this?
    }

    private OnItemRemovedFromList(object o)
    {
        // how to call this?  
    }
}

6 个答案:

答案 0 :(得分:5)

如果您正在编写自定义集合,则可以实现INotifyCollectionChangedINotifyPropertyChanged接口。他们添加了您可以订阅的事件,以便在以某种方式更改集合数据时通知侦听器 这样做,您可以订阅集合外部代码中的事件。

或者,您可以使用实现这两个接口的ObservableCollection<T>类。 INotifyCollectionChanged接口ObservableCollection<T>仅在.Net Framework 3.0及更高版本中可用。

在.Net Framework 2.0上,您可以使用IBindingList接口来获得相同的功能,但实现起来要比3.0中的INotifyCollectionChanged接口更复杂

答案 1 :(得分:3)

您还可以考虑使用System.Collections.ObjectModel.ObservableCollection<T>类,它以CollectionChanged事件的形式为您提供此类,它为您提供有关更改内容的信息。

答案 2 :(得分:2)

到目前为止,我一直使用的方法是创建一个派生自System.Collections.ObjectModel.Collection<T>的私有集合类,并直接在覆盖中调用方法:

class MyManagerClass
{
    private class MyCollection : System.Collections.ObjectModel.Collection<object>
    {
        private MyManagerClass manager;

        private MyCollection(MyManagerClass manager)
        {
            this.manager = manager;
        }

        protected override void InsertItem(int index, object item)
        {
            base.InsertItem(index, item);
            manager.OnItemAddedToList(item);
        }

        protected override void SetItem(int index, object item)
        {
            object oldItem = (index < base.Count) ? base[index] : null;
            base.SetItem(index, item);

            if (oldItem != null) {
                manager.OnItemRemovedFromList(oldItem);
            }

            manager.OnItemAddedToList(item);
        }

        protected override void RemoveItem(int index, object item)
        {
            base.RemoveItem(index, item);
            manager.OnItemRemovedFromList(item);
        }
    }

    private OnItemAddedToList(object o)    
    {
    }

    private OnItemRemovedFromList(object o)    
    {
    }
}

我不确定这是否是正确的方式,但我想看看是否有更好的选择。

答案 3 :(得分:2)

在2.0及以上版本中,BindingList<T>具有可观察集合的所有必要钩子。现在还有(如前所述)ObservableCollection<T>类,它非常相似。

在许多情况下,从Collection<T>派生新集合也是非常合理的。但是不要派生自List<T>,因为它没有(有用的)虚拟方法。

答案 4 :(得分:1)

您应该考虑使用C5 Generic Collection Library中的ArrayList,而不是使用System.Collections中的ArrayList。它包含CollectionChangedItemAdded等事件。

答案 5 :(得分:0)

我个人在IList<T>AddedRemoved个事件/代表的课程中实施Replaced。该类将具有类型为List<T>的私有实例成员,所有已实现的调用都将委托给它,以及引发事件。

如果您愿意,还可以OnBefore...OnAfter,允许您“取消”添加/删除元素。

这通常是如何完成的,但是像mookid所说的那样,可能现有的库可以做类似的事情。 DataTable类与DataRow类实现了类似的概念,包括添加,删除和更新。

您可以组合这些概念,以便添加到集合中的项目可以引发“冒泡”到集合的OnChanged个事件,并可用于在集合上重新引发ItemChanged事件。