覆盖List <t>的Add()</t>

时间:2009-10-26 17:15:34

标签: c# collections

我不能重载List的Add方法吗?

class ListDemo<T>:List<T>
 {
    public override T  Add<T>(T value)
   {
      return base.Add(value);
   }
}

我收到以下错误:

1)类型参数'T'与外部类型'CollectionsExample.ListDemo

中的类型参数同名

2)'CollectionsExample.ListDemo.Add(T)':找不到合适的方法来覆盖

6 个答案:

答案 0 :(得分:15)

您应该封装List<T>并实施List<T>,而不是从IList<T>继承。这样可以轻松处理“覆盖”Add:

的行为
public class ListDemo<T> : IList<T>
{
    private List<T> list = new List<T>(); // Internal list
    public void Add(T item)
    {
       // Do your pre-add logic here
       list.Add(item); // add to the internal list
       // Do your post-add logic here
    }

    // Implement all IList<T> methods, just passing through to list, such as:
}

List<T>不应该是您的公共API的一部分 - 它应该是一个实现细节。

答案 1 :(得分:5)

正确的代码是:

class ListDemo<T>:List<T>
{
    public new void Add(T value)
    {
      base.Add(value);
    }
}

类声明和方法都不需要类型参数。在这种情况下,它是通用的类声明;因此,当您尝试将Add方法声明为采用名为T的泛型类型参数时,编译器会抱怨您尝试使用同名的2个类型参数。

编辑:修复了代码示例。由于Add不是虚拟的,因此无法使用override关键字覆盖它(因此原始样本实际上不会编译)。您仍然可以使用new声明它,但这可能会导致Add方法的含义不同。我会强烈考虑实施IList&lt; T&gt;,正如评论中所建议的那样。

答案 2 :(得分:2)

这对我有用(根据Sam Harwell的评论):

public class ListDemo<T> : Collection<T>
{
    protected override void InsertItem(int index, T item)
    {
        // Your add condition ...
        if (!this.Any(x => ...))
            base.InsertItem(index, item);
    }
}

答案 3 :(得分:2)

如果你想要一个你想要覆盖你的添加/插入或索引器的集合,那么你可以创建一个你自己的集合,它将继承自:

Collection<T>

并覆盖以下方法:

InsertItem();
SetItem();

第一个由Add()和Insert()调用, 而第二个是由[]

调用的

List<T> Add无法覆盖,因为收集是为了表现,因此有意删除了最重要的可能性

答案 4 :(得分:1)

List<T>派生几乎总是毫无意义。请参阅我对这个其他问题的答案,了解完整的纲要:

How to create a custom collection in .NET 2.0

答案 5 :(得分:0)

从List中派生并不是没有意义的,如果那是给你所需要的类。您要做的就是添加几个方法,例如FindCar(Car dodge).