| File: System\Collections\CollectionBase.cs | Web Access |
| Project: src\runtime\src\libraries\System.Collections.NonGeneric\src\System.Collections.NonGeneric.csproj (System.Collections.NonGeneric) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. /*============================================================================= ** ** Class: CollectionBase ** ** Purpose: Provides the abstract base class for a strongly typed collection. ** =============================================================================*/ namespace System.Collections { // Useful base class for typed read/write collections where items derive from object public abstract class CollectionBase : IList { private readonly ArrayList _list; protected CollectionBase() { _list = new ArrayList(); } protected CollectionBase(int capacity) { _list = new ArrayList(capacity); } protected ArrayList InnerList { get { return _list; } } protected IList List { get { return (IList)this; } } public int Capacity { get { return InnerList.Capacity; } set { InnerList.Capacity = value; } } public int Count { get { return _list.Count; } } public void Clear() { OnClear(); InnerList.Clear(); OnClearComplete(); } public void RemoveAt(int index) { if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexMustBeLess); object? temp = InnerList[index]; OnValidate(temp!); OnRemove(index, temp); InnerList.RemoveAt(index); try { OnRemoveComplete(index, temp); } catch { InnerList.Insert(index, temp); throw; } } bool IList.IsReadOnly { get { return InnerList.IsReadOnly; } } bool IList.IsFixedSize { get { return InnerList.IsFixedSize; } } bool ICollection.IsSynchronized { get { return InnerList.IsSynchronized; } } object ICollection.SyncRoot { get { return InnerList.SyncRoot; } } void ICollection.CopyTo(Array array, int index) { InnerList.CopyTo(array, index); } object? IList.this[int index] { get { if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexMustBeLess); return InnerList[index]; } set { if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexMustBeLess); OnValidate(value!); object? temp = InnerList[index]; OnSet(index, temp, value); InnerList[index] = value; try { OnSetComplete(index, temp, value); } catch { InnerList[index] = temp; throw; } } } bool IList.Contains(object? value) { return InnerList.Contains(value); } int IList.Add(object? value) { OnValidate(value!); OnInsert(InnerList.Count, value); int index = InnerList.Add(value); try { OnInsertComplete(index, value); } catch { InnerList.RemoveAt(index); throw; } return index; } void IList.Remove(object? value) { OnValidate(value!); int index = InnerList.IndexOf(value); if (index < 0) throw new ArgumentException(SR.Arg_RemoveArgNotFound); OnRemove(index, value); InnerList.RemoveAt(index); try { OnRemoveComplete(index, value); } catch { InnerList.Insert(index, value); throw; } } int IList.IndexOf(object? value) { return InnerList.IndexOf(value); } void IList.Insert(int index, object? value) { if (index < 0 || index > Count) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexMustBeLessOrEqual); OnValidate(value!); OnInsert(index, value); InnerList.Insert(index, value); try { OnInsertComplete(index, value); } catch { InnerList.RemoveAt(index); throw; } } public IEnumerator GetEnumerator() { return InnerList.GetEnumerator(); } protected virtual void OnSet(int index, object? oldValue, object? newValue) { } protected virtual void OnInsert(int index, object? value) { } protected virtual void OnClear() { } protected virtual void OnRemove(int index, object? value) { } protected virtual void OnValidate(object value) { ArgumentNullException.ThrowIfNull(value); } protected virtual void OnSetComplete(int index, object? oldValue, object? newValue) { } protected virtual void OnInsertComplete(int index, object? value) { } protected virtual void OnClearComplete() { } protected virtual void OnRemoveComplete(int index, object? value) { } } }