Why doesn't INotifyCollectionChanged extend IList?

I came across a situation a couple of times when I want to watch a collection through an interface INotifyCollectionChanged, but also want to have access to any of the elements in the collection. The interface INotifyCollectionChangeddoes not provide any access to elements, except for those that participate in the change event (which (usually) are contained in NotifyCollectionChangedEventArgs).

Now here is my thinking:

  • We know that all tools INotifyCollectionChangedare a collection (d'uh).
  • Since it NotifyPropertyChangedEventArgscontains indexes indicating the location of the change, we know that elements can be accessed by index.

A collection that can be accessed by index is a list, so it seems to make sense to require that any constructor INotifyCollectionChangedalso implement it IList. This is easy to do if INotifyCollectionChangedstretched IList.

Does anyone know why this is not so?

+4
source share
2 answers

I think you need to look for SOLID software development principles, in particular the Liskov Principle of Replacement .

You asked why the interface INotifyCollectionChangedalso does not extend the interface IList. Let me answer it with a counter using the Liskov Subscription Principle:

, INotifyCollectionChanged - IList?

, :

  • INotifyCollectionChanged , , , , , , IList ICollection, IEnumerable, . IList, ICollection indexer

  • NotifyPropertyChangedEventArgs (, , NotifyCollectionChangedEventArgs), , , . , IList. , , .

    , .

, , INotifyCollectionChanged:

public class MyCustomCollection : INotifyCollectionChanged
{
    // This is what I meant by the "underlying collection", can be replaced with
    // ICollection<int> and it will still work, or even IEnumerable<int> but with some
    // code change to store the elements in an array
    private readonly IList<int> _ints;

    public MyCustomCollection()
    {
        _ints = new List<int>();
    }

    public event NotifyCollectionChangedEventHandler CollectionChanged;

    public void AddInt(int i)
    {
        _ints.Add(i);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(
            NotifyCollectionChangedAction.Move, 
            (IList)_ints, 
            _ints.Count,
            _ints.Count - 1));
    }

    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        var handler = CollectionChanged;
        if (handler != null)
        {
            handler(this, e);
        }
    }
}

, .

+3

, , ( - - ):

  • INotifyCollectionChanged ( , ). , . @rexcfnghk !

  • EventArgs IList<T>, ,

a Collection<T> , .

+1

All Articles