// Copyright (C) Stichting Deltares 2018. All rights reserved. // // This file is part of the Dam Engine. // // The Dam Engine is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Collections; using System.Collections.Generic; namespace Deltares.DamEngine.Data.Standard { /// /// Extends the standard List<T> class with delegates which are called on adding or removing items /// /// The generic type to create the list for /// /// /// public class VirtualList : IList, ISortableList, IList where T : class { private readonly List internalList = new List(); #region List Overrides /// /// Gets or sets the element at the specified index. /// /// The index. /// public virtual T this[int index] { get { return internalList[index]; } set { internalList[index] = value; } } /// /// Gets the number of elements contained in the . /// public virtual int Count { get { return internalList.Count; } } /// /// Gets a value indicating whether the is read-only. /// public bool IsReadOnly { get { return false; } } /// /// Adds the range. /// /// The collection. public virtual void AddRange(IEnumerable collection) { internalList.AddRange(collection); } /// /// To the array. /// /// public virtual T[] ToArray() { return internalList.ToArray(); } /// /// Adds an item to the . /// /// The object to add to the . public virtual void Add(T item) { internalList.Add(item); } /// /// Removes all items from the . /// public virtual void Clear() { internalList.Clear(); internalList.Capacity = 0; } /// /// Determines whether the contains a specific value. /// /// The object to locate in the . /// /// true if is found in the ; otherwise, false. /// public virtual bool Contains(T item) { return internalList.Contains(item); } /// /// Copies to. /// /// The array. /// Index of the array. public virtual void CopyTo(T[] array, int arrayIndex) { internalList.CopyTo(array, arrayIndex); } /// /// Removes the first occurrence of a specific object from the . /// /// The object to remove from the . /// /// true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . /// public virtual bool Remove(T item) { return internalList.Remove(item); } /// /// Determines the index of a specific item in the . /// /// The object to locate in the . /// /// The index of if found in the list; otherwise, -1. /// public virtual int IndexOf(T item) { return internalList.IndexOf(item); } /// /// Inserts an item to the at the specified index. /// /// The zero-based index at which should be inserted. /// The object to insert into the . public virtual void Insert(int index, T item) { internalList.Insert(index, item); } /// /// Removes the item at the specified index. /// /// The zero-based index of the item to remove. public virtual void RemoveAt(int index) { internalList.RemoveAt(index); } /// /// Sorts this instance. /// public virtual void Sort() { internalList.Sort(); } /// /// Reverses this instance. /// public virtual void Reverse() { internalList.Reverse(); } #endregion /// /// Returns an enumerator that iterates through a collection. /// /// /// An object that can be used to iterate through the collection. /// IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// Returns an enumerator that iterates through the collection. /// /// /// A that can be used to iterate through the collection. /// public virtual IEnumerator GetEnumerator() { return internalList.GetEnumerator(); } #region IList Members /// /// Gets a value indicating whether the has a fixed size. /// bool IList.IsFixedSize { get { return false; } } /// /// Gets a value indicating whether the is read-only. /// bool IList.IsReadOnly { get { return false; } } /// /// Gets or sets the element at the specified index. /// /// The index. /// object IList.this[int index] { get { return this[index]; } set { ThrowIfWrongType(value); this[index] = (T) value; } } /// /// Adds an item to the . /// /// The object to add to the . /// /// The position into which the new element was inserted, or -1 to indicate that the item was not inserted into the collection, /// int IList.Add(object value) { ThrowIfWrongType(value); Add((T) value); return Count - 1; } /// /// Removes all items from the . /// void IList.Clear() { Clear(); } /// /// Determines whether the contains a specific value. /// /// The object to locate in the . /// /// true if the is found in the ; otherwise, false. /// bool IList.Contains(object value) { if (!(value is T)) { return false; } return Contains((T) value); } /// /// Determines the index of a specific item in the . /// /// The object to locate in the . /// /// The index of if found in the list; otherwise, -1. /// int IList.IndexOf(object value) { if (!(value is T)) { return -1; } return IndexOf((T) value); } /// /// Inserts an item to the at the specified index. /// /// The zero-based index at which should be inserted. /// The object to insert into the . void IList.Insert(int index, object value) { ThrowIfWrongType(value); Insert(index, (T) value); } /// /// Removes the first occurrence of a specific object from the . /// /// The object to remove from the . void IList.Remove(object value) { if (value is T) { Remove((T) value); } } /// /// Removes the item at the specified index. /// /// The zero-based index of the item to remove. void IList.RemoveAt(int index) { RemoveAt(index); } #endregion #region ICollection Members /// /// Gets the number of elements contained in the . /// int ICollection.Count { get { return Count; } } /// /// Gets a value indicating whether access to the is synchronized (thread safe). /// bool ICollection.IsSynchronized { get { return false; } } /// /// Gets an object that can be used to synchronize access to the . /// object ICollection.SyncRoot { get { return null; } } /// /// Copies the elements of the to an , starting at a particular index. /// /// The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. /// The zero-based index in at which copying begins. void ICollection.CopyTo(Array array, int index) { Array.Copy(internalList.ToArray(), 0, array, index, internalList.Count); } #endregion private void ThrowIfWrongType(object item) { if (!(item is T)) { throw new InvalidCastException(); } } } }