JD2022-TU1/main/tools/framework/JD.Collections/ObjectModel/ListBase.cs

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&lt;T&gt; 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&lt;T&gt;.Contains, IList&lt;T&gt;.IndexOf and IList&lt;T&gt;.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&lt;T&gt;.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
}
}