Skip to main content
Code Review

Return to Revisions

3 of 3
replaced http://stackoverflow.com/ with https://stackoverflow.com/

Implementing IList<T>, IList & INotifyCollectionChanged

I posted this question over at Stackoverflow, which was off-topic.

I was using ObservableCollection in a number of places in my WPF application for very large arrays. This caused a problem as ObservableCollection did not take an argument for capacity like List did. This was an important optimization for locking down my memory usage and ensuring that these collections did not double to a much larger size than required.

So I implemented the following class:

public class ObservableList<T> : IList<T>, IList, INotifyCollectionChanged
{
 public event NotifyCollectionChangedEventHandler CollectionChanged;
 #region Properties
 private List<T> _List
 {
 get;
 set;
 }
 public T this[int index]
 {
 get
 {
 return _List[index];
 }
 set
 {
 if (index < 0 || index >= Count)
 throw new IndexOutOfRangeException("The specified index is out of range.");
 var oldItem = _List[index];
 _List[index] = value;
 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, oldItem, index));
 }
 }
 public int Count
 {
 get
 {
 return _List.Count;
 }
 }
 public bool IsReadOnly
 {
 get
 {
 return ((IList<T>)_List).IsReadOnly;
 }
 }
 bool IList.IsFixedSize
 {
 get
 {
 return ((IList)_List).IsFixedSize;
 }
 }
 object IList.this[int index]
 {
 get
 {
 return ((IList)_List)[index];
 }
 set
 {
 if (index < 0 || index >= Count)
 throw new IndexOutOfRangeException("The specified index is out of range.");
 var oldItem = ((IList)_List)[index];
 ((IList)_List)[index] = value;
 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, oldItem, index));
 }
 }
 public bool IsSynchronized
 {
 get
 {
 return ((IList)_List).IsSynchronized;
 }
 }
 public object SyncRoot
 {
 get
 {
 return ((IList)_List).SyncRoot;
 }
 }
 #endregion
 #region Methods
 private void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
 {
 if (CollectionChanged != null)
 CollectionChanged(this, args);
 }
 public void AddRange(IEnumerable<T> collection)
 {
 _List.AddRange(collection);
 var iList = collection as IList;
 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
 }
 public int IndexOf(T item)
 {
 return _List.IndexOf(item);
 }
 public void Insert(int index, T item)
 {
 _List.Insert(index, item);
 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
 }
 public void RemoveAt(int index)
 {
 if (index < 0 || index >= Count)
 throw new IndexOutOfRangeException("The specified index is out of range.");
 var oldItem = _List[index];
 _List.RemoveAt(index);
 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, oldItem, index));
 }
 public void Add(T item)
 {
 _List.Add(item);
 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
 }
 public void Clear()
 {
 _List.Clear();
 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
 }
 public bool Contains(T item)
 {
 return _List.Contains(item);
 }
 public void CopyTo(T[] array, int arrayIndex)
 {
 _List.CopyTo(array, arrayIndex);
 }
 public bool Remove(T item)
 {
 var result = _List.Remove(item);
 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
 return result;
 }
 public IEnumerator<T> GetEnumerator()
 {
 return _List.GetEnumerator();
 }
 IEnumerator IEnumerable.GetEnumerator()
 {
 return GetEnumerator();
 }
 int IList.Add(object value)
 {
 var result = ((IList)_List).Add(value);
 ;
 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value));
 return result;
 }
 bool IList.Contains(object value)
 {
 return ((IList)_List).Contains(value);
 }
 int IList.IndexOf(object value)
 {
 return ((IList)_List).IndexOf(value);
 }
 void IList.Insert(int index, object value)
 {
 ((IList)_List).Insert(index, value);
 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value, index));
 }
 void IList.Remove(object value)
 {
 ((IList)_List).Remove(value);
 OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, value));
 }
 public void CopyTo(Array array, int index)
 {
 ((IList)_List).CopyTo(array, index);
 }
 #endregion
 #region Initialization
 public ObservableList()
 {
 _List = new List<T>();
 }
 public ObservableList(int capacity)
 {
 _List = new List<T>(capacity);
 }
 public ObservableList(IEnumerable<T> collection)
 {
 _List = new List<T>(collection);
 }
 #endregion
}

It seems to be working fine, but I have noticed an increase in processing time since switching to this implementation. Have I implemented the interfaces correctly?

lang-cs

AltStyle によって変換されたページ (->オリジナル) /