要用于最后操作的循环列表的集合
本文关键字:循环 集合 列表 操作 用于 最后 | 更新日期: 2023-09-27 18:00:31
我正在寻找一种允许我定义最大容量的C#集合类型。我想将对象添加到此集合中,当我的容量达到时,最旧的对象应该被新的对象替换。
具体来说,我想创建一个集合来记忆我最近的10或20个动作。
我已经阅读了谷歌上的文章,但我正在从这个社区寻找答案。
.NET中唯一固定的集合类型是数组,因此它是唯一满足您需求的集合类型。
你可以保留一个索引来进行旋转。你只需要记住你下一个要写的位置是什么。
类似这样的东西:
int index = 0;
string[] collection = new string[10];
public void Write(string text)
{
index %= collection.Length; // prevent overflowing
collection[index++] = text;
}
如果您的应用程序对性能不敏感,那么您可以使用通用集合Queue
以下是可以解决您问题的包装器示例:
public class LimitedQueue<T>
{
private readonly Queue<T> _queue;
private readonly int _limit;
public LimitedQueue(int limit)
{
_queue = new Queue<T>();
_limit = limit;
}
public void Enqueue(T item)
{
if (_queue.Count == _limit) _queue.Dequeue();
_queue.Enqueue(item);
}
public T Dequeue()
{
return _queue.Dequeue();
}
public T Peek()
{
return _queue.Peek();
}
public T[] GetAll()
{
return _queue.ToArray();
}
}
它的性能不如数组,但它可以让您做一些有用的事情,比如从Queue
获取所有项。
您所描述的类型我一直称之为FixedQueue或固定大小FIFO。这个想法是先入先出,但如果超过大小,则丢弃先出:
public class FixedQueue<T>
{
private readonly ConcurrentQueue<T> _innerQueue;
private int _length;
public FixedQueue(int length)
{
_length = length;
_innerQueue = new ConcurrentQueue<T>(length);
}
public void Enqueue(T obj)
{
lock (_innerQueue)
{
if (_innerQueue.Length == _length)
_innerQueue.Dequeue();
_innerQueue.Enqueue(obj);
}
}
public T Dequeue()
{
lock (_innerQueue)
{
return _innerQueue.Dequeue();
}
}
// etc...
}
如果您正在寻找一个具有继承性的更面向对象的解决方案,并且不关心维护,那么您可以编写以下内容:
public class FixedQueue<T> : Queue<T>
{
//private readonly ConcurrentQueue<T> _innerQueue;
private int _capacity;
public FixedQueue(int capacity) : base()
{
_capacity = capacity;
}
public void Enqueue(T obj)
{
lock(this)
{
if (this.Count == _capacity)
base.Dequeue();
base.Enqueue(obj);
}
}
public T Dequeue()
{
lock (this)
{
return this.Dequeue();
}
}
}
这个解决方案不尊重新趋势,即您应该更喜欢组合而不是继承。