这里有一个想法给你。我实现了我自己的IList<T>
类,你想要做什么
首先,我开始这个(我认为):
public class RememberOrderList<T> : IList<T>
{
}
我再创造了T
的_inner
名单和实施了大部分的通过传递给_inner
所需的方法。
public class RememberOrderList<T> : IList<T>
{
private List<T> _inner = new List<T>();
public int IndexOf(T item) { return _inner.IndexOf(item); }
public void RemoveAt(int index) { _inner.RemoveAt(index); }
public T this[int index] { get { return _inner[index]; } set { _inner[index] = value; } }
public void Clear() { _inner.Clear(); }
public bool Contains(T item) { return _inner.Contains(item); }
public void CopyTo(T[] array, int arrayIndex) { _inner.CopyTo(array, arrayIndex); }
public int Count { get { return _inner.Count; } }
public bool IsReadOnly { get { return ((ICollection<T>)_inner).IsReadOnly; } }
public bool Remove(T item) { return _inner.Remove(item); }
public IEnumerator<T> GetEnumerator() { return _inner.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return _inner.GetEnumerator(); }
现在,有两种方法的项目添加到列表 - Insert
& Add
。
Insert
是一个问题,因为它指定了索引,我们不希望这样 - 所以会抛出一个NotSupportedException
。
public void Insert(int index, T item)
{
throw new NotSupportedException();
}
Add
只需要记住项目的顺序,因为它们被加入和退出之前做了排序。这需要更多的工作。
要跟踪项目的顺序,我正在使用Dictionary<T, int>
。
private readonly Dictionary<T, int> _order = new Dictionary<T, int>();
要对List<T>
进行排序,您需要一个IComparer<T>
。
private class OrderComparer : IComparer<T>
{
private readonly Dictionary<T, int> _order;
public OrderComparer(Dictionary<T, int> order)
{
_order = order;
}
public int Compare(T x, T y)
{
return _order[x].CompareTo(_order[y]);
}
}
现在Add
很容易。
public void Add(T item)
{
if (!_order.ContainsKey(item))
{
_order[item] = _order.Count;
}
_inner.Add(item);
_inner.Sort(new OrderComparer(_order));
}
把所有在一起,让我做这件事:
var rol = new RememberOrderList<int>();
rol.Add(1);
rol.Add(2);
rol.Add(3);
rol.Add(4);
rol.Add(5);
rol.Remove(2);
rol.Remove(3);
rol.Remove(4);
rol.Add(4);
rol.Add(3);
rol.Add(2);
从中我得到这个列表:
现在,只是为了避免混淆,我跑此代码再次使用20
代替2
,并得到结果{ 1, 20, 3, 4, 5 }
,因此它按期望的行为排序。
如果您需要保留一个本身并不固有排序的集合的原始顺序(例如排序列表),那么正确的方式来“删除”元素实际上是创建一个已删除不需要的元素的集合的过滤副本。或者,你将不得不保持一个单独的数据结构来跟踪从哪里删除的内容,所以你可以将订单放回原处。 – 2014-12-02 22:59:59
你是否试过使用'SortedList'? – 2014-12-02 23:03:27
指定“它必须显示”的含义。如果仅用于显示目的,则提供返回已排序项目的方法。你可以很容易地做到这一点:'string.Join(“,”,list.OrderBy(x => x))' – 2014-12-02 23:04:31