142 lines
4.2 KiB
C#
142 lines
4.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
|
|
namespace JD.Collections.ObjectModel
|
|
{
|
|
/// <summary>
|
|
/// ListBase is a base class that can be used to more easily implement the
|
|
/// generic IList<T> interfaces.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>To use ListBase as a base class, the derived class must override
|
|
/// the Count, GetEnumerator, GetItem and SetItem methods. </para>
|
|
/// <para>ICollection<T>.Contains, IList<T>.IndexOf and IList<T>.Insert need not be implemented by the
|
|
/// derived class, but it should be strongly considered, because the ListBase implementation
|
|
/// may not be very efficient. </para>
|
|
/// <para>IList<T>.RemoveAt may also be Considered if the implementation of GetItem is not efficient. </para>
|
|
/// </remarks>
|
|
/// <typeparam name="T">The item type of the collection.</typeparam>
|
|
[Serializable]
|
|
[DebuggerDisplay("{DebuggerDisplayString()}")]
|
|
public abstract class ListBase<T> : CollectionBase<T>, IList<T>
|
|
{
|
|
#region IList<T> Members
|
|
|
|
/// <summary>
|
|
/// IndexOf.
|
|
/// </summary>
|
|
/// <remarks>Consider reimplementing this method for better performance.</remarks>
|
|
/// <param name="item"></param>
|
|
/// <returns></returns>
|
|
public virtual int IndexOf(T item)
|
|
{
|
|
for (int i = 0; i < Count; i++)
|
|
{
|
|
if (Equals(this[i], item))
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Insert.
|
|
/// </summary>
|
|
/// <remarks>Consider reimplementing this method for better performance.</remarks>
|
|
/// <param name="index"></param>
|
|
/// <param name="item"></param>
|
|
public virtual void Insert(int index, T item)
|
|
{
|
|
if (index == Count)
|
|
{
|
|
Add(item);
|
|
return;
|
|
}
|
|
|
|
Add(this[Count - 1]);
|
|
|
|
int i = Count - 2;
|
|
for (; i > index; --i)
|
|
{
|
|
this[i] = this[i - 1];
|
|
}
|
|
|
|
this[i] = item;
|
|
}
|
|
|
|
/// <summary>
|
|
/// RemoveAt.
|
|
/// </summary>
|
|
/// <remarks>The performance of this methods depends of the performance of GetItem method.</remarks>
|
|
/// <param name="index"></param>
|
|
public abstract void RemoveAt(int index);
|
|
|
|
/// <summary>
|
|
/// Indexer.
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <returns></returns>
|
|
public T this[int index]
|
|
{
|
|
get { return GetItem(index); }
|
|
set { SetItem(index, value); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the item at the given <paramref name="index"/>.
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <returns></returns>
|
|
protected abstract T GetItem(int index);
|
|
|
|
/// <summary>
|
|
/// Set the item at the given <paramref name="index"/>.
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <param name="value"></param>
|
|
/// <returns></returns>
|
|
protected abstract void SetItem(int index, T value);
|
|
|
|
/// <summary>
|
|
/// Overriden.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public override IEnumerator<T> GetEnumerator()
|
|
{
|
|
return GetEnumerable().GetEnumerator();
|
|
}
|
|
|
|
private IEnumerable<T> GetEnumerable()
|
|
{
|
|
for (int i = 0; i < Count; i++)
|
|
{
|
|
yield return GetItem(i);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Utility
|
|
|
|
/// <summary>
|
|
/// Removes the item finding its index in the list. (for those who prefers implementing the RemoveAt instead of the remove).
|
|
/// </summary>
|
|
/// <param name="item"></param>
|
|
/// <returns></returns>
|
|
protected bool RemoveByIndex(T item)
|
|
{
|
|
int index = IndexOf(item);
|
|
if (index >= 0)
|
|
{
|
|
RemoveAt(index);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|