为什么派生一个List <t>类只是为了重述一个索引器?</t>

时间:2012-03-19 15:26:50

标签: c# list inheritance

我一直看到List派生类看起来像这样

class MyClassList : List<MyClass>
{
    public MyClass this[int index]
    {
        get { return (MyClass)base[index]; }
    }
}

这种继承有什么意义?看起来它只是重述了成员的铸造。我可以理解其他类型的索引器,但这只是对默认List索引器的重述,并引发Visual Studio警告RE:隐藏基本索引器。这是正确的还是错的,为什么?

7 个答案:

答案 0 :(得分:5)

也许是非常差尝试阻止通过索引器覆盖值?

MyClassList x = new MyClassList();
x.Add(new MyClass());
x[0] = new MyClass(); // Error!

当然,它并没有阻止这一点:

List<MyClass> x = new MyClassList();
x.Add(new MyClass());
x[0] = new MyClass(); // No problem here...

基本上,这是一个坏主意。遗憾的是,糟糕的代码很多 - 不仅仅是因为存在而推断出有用性:(

答案 1 :(得分:2)

这没有充分的理由。它隐藏基本索引器而不是覆盖它,这可能是危险的,并且它根本没有任何效果。

在大多数情况下,最好直接使用 List<MyClass>。如果您不打算扩展List<>的功能,则无需为此创建特殊类。

答案 2 :(得分:1)

我认为没有任何用处。 此外,演员阵容是不必要的。

答案 3 :(得分:1)

我认为它应该隐藏基类的set访问器,使它看起来像索引器是只读的。但它没用,因为它很容易解决:

MyClassList list = ...

((List<MyClass>)list)[index] = value;

无论如何,List<T>类不是为继承而设计的。如果您需要创建专门的集合,请继承Collection<T>

答案 4 :(得分:0)

在人们想要将其作为另一种类型进行序列化之前,我已经看过这种类型的东西,现在如果那是那里唯一的代码而且由于其他原因它不需要是MyClassList类型,它完全没有意义。 / p>

答案 5 :(得分:0)

这基本上是尝试以正确覆盖对[]的{​​{1}}访问权限,以实现一些自定义元素访问逻辑。

值得提及的是,提供的代码不是很好,如果不是危险。如果你想用list做一些棘手的事情,请不要覆盖(或倾向于这样做)List,但为此目的实现一些自定义方法。

答案 6 :(得分:0)

我的猜测是代码试图表现为只读List。一个人无法通过索引写入MyClassList<T>类型变量的项目,尽管可以将其强制转换回List<T>并以此方式编写变量。有时候有一个类型能力有限的变量是有意义的,持有一个实际能力要大得多的对象。但是,正确的方法是使用接口,一个主要的例子是IEnumerable<T>。如果将List<T>传递给接受IEnumerable<T>类型参数的例程,则例程可以将其参数强制转换回List<T>并使用Add()之类的成员,{{1但是,必须接受类型为Remove()的参数的例程不会尝试将其用作其他任何内容。

原始海报所显示的代码风格的一个主要问题是,更“强大”的方向是基础,而不是派生类型。因为IEnumerable<T>派生自List<T>,这意味着可以枚举IEnumerable<T>的所有实例,但不仅一些可枚举的内容在List<T>中具有额外的功能。相比之下,在实施课程时,每个List<T>都可以被读取和写入,但只有MyClassList<T>的某些实例可以用作List<T>