如何重写List <T>在C#中的Add方法?
我目前正在寻找自己的collections,这将像一个常规列表,除了它只能容纳10个项目。 如果在列表中已经有10个项目时添加项目,则在添加新项目之前,第一个项目将被删除。
我想要做的是创build一个扩展System.Collections.Generic.List<T>
的类,然后修改Add(T item)
方法以包含删除第一个项目的function(如有必要)。
首先,你不能覆盖Add,并且仍然对List有多态性,这意味着如果你使用new关键字,并且你的类被转换为List,你的新的Add方法将不会被调用。
其次,我build议你看一下Queue类,因为你所要做的更多的是队列而不是列表。 这个类是完全按照你想要做的来进行优化的,但是没有任何的大小限制器。
如果你真的想要像List一样行事,但像一个最大尺寸的Queue一样工作,我build议你实现IList并保留一个Queue实例来存储你的元素。
例如:
public class LimitedQueue<T> : IList<T> { public int MaxSize {get; set;} private Queue<T> Items = new Queue<T>(); public void Add(T item) { Items.Enqueue(item); if(Items.Count == MaxSize) { Items.Dequeue(); } } // I'll let you do the rest }
你也可以通过实现add方法
public new void Add(...)
在派生类中隐藏现有的添加并引入您的function。
编辑:粗糙的轮廓…
class MyHappyList<T> : List<T> { public new void Add(T item) { if (Count > 9) { Remove(this[0]); } base.Add(item); } }
只是一个说明,认为它是隐含的,但你必须总是引用你的自定义列表的实际types,而不是由基types/接口作为隐藏方法只适用于你的types和进一步派生types。
你不能重写Add(),它不是一个虚拟的方法。 而是从IList派生出来,并使用一个私有的Queue成员来实现。
您可以扩展System.Collections.ObjectModel.Collection并重写InsertItem方法来获取所需的行为,并且还实现IList
你可以写一个实现了IList<T>
的类,该类持有一个内部的List<T>
并且编写你自己的方法。
看来我能做的最好的是这样的:
class MostRecentList<T> : System.Collections.Generic.List<T> { private int capacity; public MostRecentList(int capacity) : base() { this.capacity = capacity; } public new void Add(T item) { if (base.Count == capacity) { base.RemoveAt(0); } base.Add(item); } }
由于add()
方法没有标记为虚拟的。
您对您的要求的描述听起来像是一个循环缓冲区 。
我实现了我自己的 – 与CodePlex上的这个实现类似,除了我的实现IList<T>
。
其他一些答案build议使用Queue<T>
– 但这不完全相同,因为它只允许FIFO访问。
总的来说,不build议从List<T>
派生,而是从Collection<T>
派生,并实现所需的其他任何东西。 但是对于循环缓冲区,使用私有数组可能更合适,而不是像CodePlex实现那样从Collection<T>
派生。
阅读Liskovreplace原则 ,你的集合是扩展List <T>
一个非常差的候选者,它甚至不是执行IList <T>
的好候选者。
这些数据需要什么样的读取模式? 如果您只需要查看所有当前条目,那么实现IEnumerable <T>
和Add(T)方法就足够了。
这可以通过一个私有队列来实现(或者Deque会更好,但是这样的集合会需要一些其他的集合API,我不build议你自己实现一个)Enqueue()在Add(with Dequeue的if需要保持大小)。
请注意,实现IEnumerable并提供Add方法意味着您仍然可以使用Collection初始化语法(如果需要)。
如果你需要随机访问值,那么实现一个索引器可能是一个好主意,但我不明白这会给你什么好处,没有更多的上下文的问题。
你可以看看C5collections库。 他们有一个实现IList <T>的ArrayList <T>,并有一个虚拟的Add方法。 C5集合库是一个很好的列表,队列,堆栈等等…你可以在这里findC5库:
您可以尝试扩展System.Collections.ObjectModel.Collection<T>
,它更加灵活。 然后,您可以重写受保护的成员InsertItem
和SetItem
,以自定义您的集合的行为。