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; }
}
}