using System; using System.Collections; using System.Collections.Generic; namespace Chernobyl.Collections.Generic { /// /// A list that holds its items in instances. /// /// The type to hold in the list public class WeakReferenceList : IList where T : class { /// /// Initializes a new instance of the /// class. /// public WeakReferenceList() : this(0) { } /// /// Initializes a new instance of the /// class. /// /// The capacity of the new list. public WeakReferenceList(int capacity) { TheList = new List>(capacity); } /// /// Removes all items that are no longer alive (see /// ). /// public int Clean() { return TheList.RemoveAll((wr) => wr.IsAlive == false); } /// /// 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 int IndexOf(T item) { return TheList.FindIndex((wr) => wr.Target == 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 /// . /// /// is not a valid index in the /// . /// The /// is read-only. public void Insert(int index, T item) { TheList.Insert(index, new WeakReference(item)); } /// /// Removes the item at the specified index. /// /// The zero-based index of the item to remove. /// /// is not a valid index in the /// . /// The /// is read-only. public void RemoveAt(int index) { TheList.RemoveAt(index); } /// /// Gets or sets the item at the specified index. /// public T this[int index] { get { return TheList[index].Target; } set { TheList[index].Target = value; } } /// /// Adds an item to the . /// /// The object to add to the /// . /// The /// is read-only. public void Add(T item) { TheList.Add(new WeakReference(item)); } /// /// Removes all items from the . /// /// The /// is read-only. public void Clear() { TheList.Clear(); } /// /// Determines whether the contains a /// specific value. /// /// The object to locate in the /// . /// /// true if is found in the /// ; otherwise, false. /// public bool Contains(T item) { return TheList.Exists((wr) => wr.Target == item); } /// /// 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. /// /// is null. /// /// is less than 0. /// /// is multidimensional or /// is equal to or greater than the length /// of .-or-The number of elements in the source /// is greater than the available space from /// to the end of the destination /// .-or-Type cannot be cast /// automatically to the type of the destination . /// public void CopyTo(T[] array, int arrayIndex) { if (arrayIndex < 0) throw new ArgumentException("The index into the array cannot be less than zero.", "arrayIndex"); if (arrayIndex >= array.Length) throw new ArgumentOutOfRangeException("The index into the array cannot exceed the arrays length", "arrayIndex"); if (array.Length - arrayIndex < Count) throw new ArgumentOutOfRangeException("There is not enough room in the array to fit the requested contents of the list."); int currentListIndex = 0; for (int i = arrayIndex; i < array.Length; ++i) { array[i] = TheList[currentListIndex].Target; ++currentListIndex; } } /// /// Gets the number of elements contained in the /// . /// /// /// The number of elements contained in the /// . public int Count { get { // clean out the list first to ensure we have an accurate count Clean(); return TheList.Count; } } /// /// Gets a value indicating whether the is /// read-only. /// /// /// true if the is read-only; /// otherwise, false. public bool IsReadOnly { get { return false; } } /// /// 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 /// . /// /// The /// is read-only. public bool Remove(T item) { int count = TheList.Count; TheList.RemoveAll((wr) => wr.Target == item); // if the last count of the list is greater than the new count, then // the item was removed. return count > TheList.Count; } /// /// Returns an enumerator that iterates through the collection. /// /// /// A that can be used to /// iterate through the collection. /// public IEnumerator GetEnumerator() { return new WeakReferenceEnumerator(TheList.GetEnumerator()); } /// /// Returns an enumerator that iterates through a collection. /// /// /// An object that can be used /// to iterate through the collection. /// IEnumerator IEnumerable.GetEnumerator() { return new WeakReferenceEnumerator(TheList.GetEnumerator()); } /// /// Holds the item in the list. /// List> TheList { get; set; } } }