关于.NET:c# List 的继承问题

C#: Inheritance Problem with List<T>

让我们假设这节课是C:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class LimitedList<T> : List<T>
{
    private int _maxitems = 500;

    public void Add(T value) /* Adding a new Value to the buffer */
    {
        base.Add(value);
        TrimData(); /* Delete old data if lenght too long */
    }

    private void TrimData()
    {
        int num = Math.Max(0, base.Count - _maxitems);
        base.RemoveRange(0, num);
    }
}

编译器在"public void add(t value)"行中给出此警告:

warning CS0108: 'System.LimitedList.Add(T)' hides inherited member 'System.Collections.Generic.List.Add(T)'. Use the new keyword if hiding was intended.

我该怎么做才能避免这个警告?

谢谢你的帮助4


不-不要在这里使用new;这不会提供多态性。List不打算以这种方式继承;使用CollectionoverridetheAdds>InsertItem方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class LimitedCollection<T> : Collection<T>
{
    private int _maxitems = 500;

    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);
        TrimData(); /* Delete old data if lenght too long */
    }

    private void TrimData()
    {
        int num = Math.Max(0, base.Count - _maxitems);
        while (num > 0)
        {
            base.RemoveAt(0);
            num--;
        }
    }
}


您可以通过在声明中添加"new"来避免此警告。

1
2
3
public new void Add(T value) {
 ...
}

不过,我认为通过使用继承,您可能会处理这个问题有点错误。从我的角度来看,limitedList不是一个列表,因为它表达了非常不同的行为,因为它对列表中的数据量施加了严格的限制。我认为最好不要从列表继承,而是将列表作为成员变量。

这是一个坏主意的另一个原因是当你的班级的合同被视为一个列表时,你将不能满足它。下面的代码将使用列表的add方法而不是limitedList。

1
2
3
4
List<int> list = new LimitedList<int>(10);
for ( i = 0; i < 10000; i++ ) {
  list.Add(i);
}


您需要将"Add"方法声明为"New"(替换)方法。试试这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class LimitedList<T> : List<T>
{
    private int _maxitems = 500;

    public new void Add(T value) /* Adding a new Value to the buffer */
    {
        base.Add(value);
        TrimData(); /* Delete old data if length too long */
    }

    private void TrimData()
    {
        int num = Math.Max(0, base.Count - _maxitems);
        base.RemoveRange(0, num);
    }
}

注意"add(…"声明中的"new"关键字。

不过,在本例中,您应该创建自己的实现IList接口的泛型类。希望有帮助。


正如其他人所说,您需要添加新的关键字。这是因为在基类(list)中,add方法没有用关键字"virtual"标记,这基本上意味着"overridable"。因此,应标记为"新"。