C# - 有限列表还是有限列表?

时间:2013-12-03 20:43:39

标签: c#

我想知道C#中的某个功能......

我想要一个List<Object> MyList();,我可以.Add(new Object())有限次数。假设我添加了5个项目,如果我要添加第6个,那么最后一个项目将被销毁,第六个元素将被放在列表的顶部。

c#中有没有内置机制可以做到这一点?

4 个答案:

答案 0 :(得分:2)

没有内置集合可以执行此操作,但您可以轻松创建自己的类,其中包含在添加项目时具有此行为的内部列表。它并不是特别困难,但是写出标准列表将使用的所有方法并实现所有接口List可能会有点乏味。

答案 1 :(得分:1)

在我的核心库中,我有一个名为LimitedQueue<T>的东西。这可能与您所追求的类似(您可以轻松将其修改为List<T>)。 (Source on GitHub

using System.Collections.Generic;

namespace Molten.Core
{
    /// <summary>
    /// Represents a limited set of first-in, first-out objects.
    /// </summary>
    /// <typeparam name="T">The type of each object to store.</typeparam>
    public class LimitedQueue<T> : Queue<T>
    {
        /// <summary>
        /// Stores the local limit instance.
        /// </summary>
        private int limit = -1;

        /// <summary>
        /// Sets the limit of this LimitedQueue. If the new limit is greater than the count of items in the queue, the queue will be trimmed.
        /// </summary>
        public int Limit
        {
            get
            {
                return limit;
            }
            set
            {
                limit = value;
                while (Count > limit)
                {
                    Dequeue();
                }
            }
        }

        /// <summary>
        /// Initializes a new instance of the LimitedQueue class.
        /// </summary>
        /// <param name="limit">The maximum number of items to store.</param>
        public LimitedQueue(int limit)
            : base(limit)
        {
            this.Limit = limit;
        }

        /// <summary>
        /// Adds a new item to the queue. After adding the item, if the count of items is greater than the limit, the first item in the queue is removed.
        /// </summary>
        /// <param name="item">The item to add.</param>
        public new void Enqueue(T item)
        {
            while (Count >= limit)
            {
                Dequeue();
            }
            base.Enqueue(item);
        }
    }
}

您可以这样使用它:

LimitedQueue<int> numbers = new LimitedQueue<int>(5);
numbers.Enqueue(1);
numbers.Enqueue(2);
numbers.Enqueue(3);
numbers.Enqueue(4);
numbers.Enqueue(5);
numbers.Enqueue(6); // This will remove "1" from the list
// Here, "numbers" contains 2, 3, 4, 5, 6 (but not 1).

答案 2 :(得分:1)

如Servy所说,Framework中没有内置集合。但是,您可以像这样制作一个CircularBuffer -

enter image description here

namespace DataStructures
{
    class Program
    {
        static void Main(string[] args)
        {
            var buffer = new CircularBuffer<int>(capacity: 3);

            while (true)
            {
                int value;
                var input = Console.ReadLine();

                if (int.TryParse(input, out value))
                {
                    buffer.Write(value);
                    continue;
                }
                break;
            }

            Console.WriteLine("Buffer: ");
            while (!buffer.IsEmpty)
            {
                Console.WriteLine(buffer.Read());
            }
            Console.ReadLine();
        }
    }
}

namespace DataStructures
{
    public class CircularBuffer<T>
    {
        private T[] _buffer;
        private int _start;
        private int _end;

        public CircularBuffer()
            : this(capacity: 3)
        {
        }

        public CircularBuffer(int capacity)
        {
            _buffer = new T[capacity + 1];
            _start = 0;
            _end = 0;
        }

        public void Write(T value)
        {
            _buffer[_end] = value;
            _end = (_end + 1) % _buffer.Length;
            if (_end == _start)
            {
                _start = (_start + 1) % _buffer.Length;
            }
        }

        public T Read()
        {
            T result = _buffer[_start];
            _start = (_start + 1) % _buffer.Length;
            return result;
        }

        public int Capacity
        {
            get { return _buffer.Length; }
        }

        public bool IsEmpty
        {
            get { return _end == _start; }
        }

        public bool IsFull
        {
            get { return (_end + 1) % _buffer.Length == _start; }
        }
    }
}

以上代码来自PluralSight - Scott Allen's C# Generics

答案 3 :(得分:-1)

您可以使用固定大小的队列。之后只需调用.ToList()。

Fixed size queue which automatically dequeues old values upon new enques