继承自List <T>

pis*_*hio 41 c# collections inheritance list

实现继承自的新类的最快方法是什么List<T>

class Animal {}

class Animals : List<Animal> {} // (1)
Run Code Online (Sandbox Code Playgroud)

我遇到的一个问题:通过简单地做(1),我发现我没有从继承任何构造函数中获益List<T>.

最后,我想Animals表现得很像List<T>(例如,可以构建,与Linq的兼容性).但另外,我还希望能够添加自己的自定义方法.

Joã*_*elo 48

如果你想创建一个公开暴露的动物集合,你不应该继承List<T>,而是继承Collection<T>并使用Collection类名中的后缀.示例:AnimalCollection : Collection<Animal>.

这得到框架设计指南的支持,更具体地说:

不要使用ArrayList,List<T>, Hashtable,或Dictionary<K,V>在公共API.使用Collection<T>, ReadOnlyCollection<T>, KeyedCollection<K,T>,或CollectionBase的亚型代替.请注意,通用集合仅在Framework 2.0及更高版本中受支持.

  • 我不明白为什么我应该遵循这个准则. (79认同)
  • @Martinho:也许'因为你无法覆盖添加/删除方法,而使用`Collection <T>`你可以.顺便说一句,我更喜欢使用内部`List <T>`来实现`IList <T>`或`ICollection <T>`,而不是继承自`Collection <T>`... (8认同)
  • 还考虑使用接口,即ICollection <T>,IEnumerable <T>,IDictionary <TKey,TValue>等. (7认同)
  • @Martinho Fernandes,这是一个*指南*与其他任何指南一样,但如果您在公共API中提供类型集合,您可以在将来的版本中更改它,因为它是您的类型.如果你直接使用List <T>,那你就不走运了. (5认同)

And*_*mes 25

构造函数不会与类一起继承.你必须重新实现你想要的构造函数.

public class AnimalsCollection : List<Animal>
{
     public AnimalsCollection(IEnumerable<Animal> animals) : base(animals) {} 
}
Run Code Online (Sandbox Code Playgroud)

  • Downvoters想说出为什么?他问为什么他"没有任何建设者",这就是为什么我的回答是这样的.如果你不同意,那么留下一些反馈怎么样? (10认同)
  • 与Tokk相同的原因.但这再一次表明为什么匿名的downvotes很糟糕:它只是没有帮助. (4认同)
  • @George Stocker:这仍然不是OP的问题.给他一个更好的方向推动是件好事,但我有点讨厌在回答这个人的实际问题之前我们必须分析每个人的方法.知道构造函数不是继承的,本身就是一个有用的东西. (2认同)
  • @Anderson 是的,但这里的普遍观点不是授人以渔,而是教他们钓鱼。*也就是说*,我不会否决这个答案,我只能再说一遍,匿名否决票很糟糕。 (2认同)

Eup*_*ric 12

List<T>不建议派生.主要是因为List从来没有用于扩展,而是用于性能.

如果要创建自己的特定集合,则应继承Collection<T>.在你的情况下,它将是:

class Animals : Collection<Animal> {}
Run Code Online (Sandbox Code Playgroud)

  • @shashwat它没有那些方法,因为`Collection`应该是表示任何项目组的通用类.例如,数学集没有特定的顺序,也无法排序.如果元素不是唯一的,`Find`可能是不明确的.这两种情况都应该是'Collection`可以用来的一部分,所以它不能包括`Sort`和`Find`而不失一般性.虽然应该有一个`ListCollection:Collection`,因为它似乎是人们最常用的. (3认同)
  • 我按照你的建议做了,继承自`Collection <MyClass>`.但是像"Collection <T>"这样的问题不支持像`Sort`,`Find`,`FindAll`这样的方法以及更多非常有用的方法.我必须将其更改为继承自`List <MyClass>`.有什么我能做的吗? (2认同)

Ada*_*rth 6

请记住,从List继承并不像您可能需要的那样功能齐全,很多成员都不是虚拟的,因此覆盖基本实现的唯一方法是用new语法(而不是override)来遮蔽它.

如果您需要开始在标准列表操作上公开自定义行为,我将在一个类型上实现所有列表接口,该类型仅使用实际存储的内部列表.

这在很大程度上取决于您的最终要求.

  • @shashwat`Sorted`,`Find`和`FindAll`等可以用LINQ实现`IEnumerable <T>`,所以这不是问题. (3认同)