Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何覆盖列表<;T>';s在C#中添加方法?_C#_Generics_Inheritance_Collections - Fatal编程技术网

如何覆盖列表<;T>';s在C#中添加方法?

如何覆盖列表<;T>';s在C#中添加方法?,c#,generics,inheritance,collections,C#,Generics,Inheritance,Collections,我目前正在寻找我自己的收集,这将就像一个普通的名单,除了它将只容纳10个项目。如果在列表中已有10个项目时添加了一个项目,那么在添加新项目之前,第一个项目将被删除 我想做的是创建一个扩展System.Collections.Generic.List的类,然后修改Add(T item)方法,以包含必要时删除第一项的功能。您不能重写Add(),它不是虚拟方法。改为从IList派生并使用专用队列成员进行实现。您只需编写一个实现IList的类,该类包含一个内部的列表,并编写自己的方法。您还可以通过 pu

我目前正在寻找我自己的收集,这将就像一个普通的名单,除了它将只容纳10个项目。如果在列表中已有10个项目时添加了一个项目,那么在添加新项目之前,第一个项目将被删除


我想做的是创建一个扩展
System.Collections.Generic.List
的类,然后修改
Add(T item)
方法,以包含必要时删除第一项的功能。

您不能重写Add(),它不是虚拟方法。改为从IList派生并使用专用队列成员进行实现。

您只需编写一个实现IList的类,该类包含一个内部的
列表,并编写自己的方法。

您还可以通过

public new void Add(...)
在派生类中隐藏现有的添加和介绍功能

编辑:粗略的轮廓

class MyHappyList<T> : List<T>
{
    public new void Add(T item)
    {
        if (Count > 9)
        {
            Remove(this[0]);
        }

        base.Add(item);
    }
}
类MyHappyList:列表
{
新增公共作废(T项)
{
如果(计数>9)
{
删除(此[0]);
}
基础。添加(项目);
}
}

只是一个注释,我认为这是隐含的,但您必须始终按实际类型引用自定义列表,而决不能按基类型/接口引用,因为隐藏方法仅适用于您的类型和其他派生类型。

似乎我能做的最好的事是:

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);
        }
}
类MostRecentList:System.Collections.Generic.List{
私人int能力;
公共MOST中心列表(内部容量):基本(){
这个。容量=容量;
}
新增公共作废(T项){
if(base.Count==容量){
基。移除(0);
}
基础。添加(项目);
}
}

由于
add()
方法没有标记为virtual。

首先,您不能覆盖add,并且仍然具有针对的多态性,这意味着如果您使用new关键字并且将类强制转换为列表,则不会调用新的add方法

其次,我建议你深入课堂,因为你要做的更多的是一个队列而不是一个列表。该类针对您想要做的事情进行了优化,但没有任何类型的大小限制

如果您真的希望某些东西像列表一样工作,但像最大大小的队列一样工作,我建议您实现并保留一个队列实例来存储元素

例如:

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
}
公共类受限队列:IList
{
public int MaxSize{get;set;}
专用队列项目=新队列();
公共作废新增(T项)
{
项目。排队(项目);
如果(Items.Count==MaxSize)
{
Items.Dequeue();
}
}
//剩下的我让你来做
}

您可以查看C5集合库。它们有一个实现IList的ArrayList和一个虚拟Add方法。C5集合库是一个非常棒的列表、队列、堆栈等集合。。。您可以在此处找到C5库:

请阅读,您的集合对于扩展列表来说是一个非常糟糕的候选者,它甚至不是实现IList
的理想候选者

此数据需要什么读取模式?如果只需要查看所有当前条目,那么实现IEnumerable
和Add(T)方法就足够了

然后可以通过一个私有队列(或者Deque会更好,但这样的集合需要一些其他集合API,我不建议您自己尝试实现),在添加过程中将其放入队列()(如果需要保持大小,可以使用Dequeue)

请注意,实现IEnumerable并提供Add方法意味着您仍然可以在需要时使用集合初始化器语法


如果您需要随机访问这些值,那么实现索引器可能是一个好主意,但如果没有更多关于这个问题的上下文,我看不出这会给您带来什么好处。

您可以扩展并覆盖InsertItem方法以获得所需的行为,它还实现了IList

您对需求的描述听起来像是一个简单的例子

我实现了自己的-与类似,只是我的实现了
IList

其他一些答案建议使用
队列
——但这不是一回事,因为它只允许FIFO访问


一般来说,不建议从
列表
派生,而是从
集合
派生,并实现您需要的任何其他内容。但是对于循环缓冲区,可能更适合使用私有数组,而不是像CodePlex实现那样从
集合
派生。

您可以尝试扩展
System.Collections.ObjectModel.Collection
,它更灵活。然后,您可以覆盖受保护的成员
InsertItem
SetItem
,以自定义集合的行为。

我同意,我认为队列是这种情况下的最佳选择。请记住,我建议的代码决不是线程安全的。你必须自己做这件事。:)@昆汀:的确,我同意,先生。“就像一个普通的列表,除了它只能容纳10个项目”听起来更像是一个循环缓冲区,而不是一个队列。请看我的答案。这是一个非常糟糕的想法,根据用于发送Add消息的变量类型,您的类的行为不再正确。实际上,您需要仔细阅读LSP及其描述的可替换性。请记住,如果使用此方法,如果将类转换为列表,则该类将无法工作。您的新Add方法将永远不会被调用。你真的应该考虑使用一个队列。@ ShuggyCoUk LSP意味着什么?收藏不允许我重写Addit。显然,当我打算投票时,我否决了这一点,现在就意识到,我不能改变它: