【问题标题】:Inheriting from List<T>从 List<T> 继承
【发布时间】:2011-07-19 13:44:03
【问题描述】:

实现从List&lt;T&gt; 继承的新类的最快方法是什么?

class Animal {}

class Animals : List<Animal> {} // (1)

我遇到的一个问题:通过简单地执行 (1),我发现我没有从List&lt;T&gt; 继承任何构造函数的好处。

最后,我希望Animals 的行为更像List&lt;T&gt;(例如,可以构造,与Linq 兼容)。但除此之外,我还希望能够添加我自己的自定义方法。

【问题讨论】:

  • 你发布的内容我觉得不错!
  • 你上面的代码可以做到。您将需要实现任何构造函数,只需在基调用 (List) 上调用相关构造函数。您可以在 Animals 类中创建任何自定义方法

标签: c# list inheritance collections


【解决方案1】:

如果你想创建一个公开动物集合,你不应该从List&lt;T&gt;继承,而是从Collection&lt;T&gt;继承并在类名中使用后缀Collection。示例:AnimalCollection : Collection&lt;Animal&gt;

framework design guidelines 支持此功能,更具体地说:

请勿使用ArrayListList&lt;T&gt;HashtableDictionary&lt;K,V&gt; 在 公共 API。使用Collection&lt;T&gt;ReadOnlyCollection&lt;T&gt;, KeyedCollection&lt;K,T&gt;,或 CollectionBase 子类型。笔记 通用集合只是 在框架版本 2.0 中支持 及以上。

【讨论】:

  • 我不明白为什么我应该遵循这个准则。
  • +1 如果 OP 想要在列表本身中做某事,这真的很有意义。OP 可以覆盖基本方法。我真的没有看到继承自 List&lt;T&gt; 的任何其他值只是为了调用您的列表类型 Animal 对吗?
  • @Martinho Fernandes,它是一个指南,与任何其他指南一样,但如果您在公共 API 中提供类型化集合,您可以在未来的版本中更改它,因为它是您的类型。如果你直接使用 List,那你就不走运了。
  • 还可以考虑使用接口,即 ICollection、IEnumerable、IDictionary 等。
  • @Martinho:也许是因为你不能覆盖 Add/Remove 方法,而使用 Collection&lt;T&gt; 你可以。顺便说一句,我更喜欢使用内部List&lt;T&gt; 来实现IList&lt;T&gt;ICollection&lt;T&gt;,而不是从Collection&lt;T&gt;继承...
【解决方案2】:

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

public class AnimalsCollection : List<Animal>
{
     public AnimalsCollection(IEnumerable<Animal> animals) : base(animals) {} 
}

【讨论】:

  • 投反对票的人想说为什么?他问为什么他“没有任何构造函数”,这就是为什么我的回答是这样的。如果您不同意,请留下一些反馈意见如何?
  • 与 Tokk 的原因相同。但这再次说明了为什么匿名投票很糟糕:它只是没有帮助。
  • 参见:stackoverflow.com/questions/3748931/stackoverflow.com/questions/898152/stackoverflow.com/questions/794679/stackoverflow.com/questions/5207459/stackoverflow.com/questions/2136213/ stackoverflow.com/questions/349904 stackoverflow.com/questions/1257214
  • @George Stocker:这仍然不是 OP 的问题。让他朝着更好的方向轻推是件好事,但我有点讨厌我们必须在回答每个人的实际问题之前分析每个人的方法。知道构造函数不是继承的本身就是一件有用的事情。
  • @Anderson 是的,但这里的普遍情绪不是给 OP 一条鱼,而是教他们钓鱼。 也就是说,我不会对这个答案投反对票,我只能再说一遍,匿名投反对票很糟糕。
【解决方案3】:

不建议从List&lt;T&gt; 派生。主要是因为 List 从来不是为了扩展,而是为了性能。

如果您想创建自己的特定集合,您应该从Collection&lt;T&gt; 继承。在您的情况下,它将是:

class Animals : Collection<Animal> {}

【讨论】:

  • 我按照你的建议做了,继承自Collection&lt;MyClass&gt;。但是像Collection&lt;T&gt; 这样的问题不支持SortFindFindAll 等方法以及更多非常有用的方法。我必须将其更改为从List&lt;MyClass&gt; 继承。有什么我能做的吗?
  • @shashwat 它没有这些方法,因为 Collection 应该是表示任何项目组的通用类。例如,一个数学集合没有特定的顺序,也不能排序。如果元素不是唯一的,Find 可能会模棱两可。这两种情况都应该是Collection 可用于的一部分,因此它不能包括SortFind 而不会失去一般性。虽然可能应该有一个ListCollection : Collection,因为这似乎是人们最常使用它的原因。
【解决方案4】:

请记住,从 List 继承的功能并不像您可能需要的那样全面,许多成员不是虚拟的,因此覆盖基本实现的唯一方法是使用 new 语法(如反对override)。

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

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

【讨论】:

  • 我按照你的建议做了,继承自Collection&lt;MyClass&gt;。但是像Collection&lt;T&gt; 这样的问题不支持SortFindFindAll 等方法以及更多非常有用的方法。我必须将其更改为从List&lt;MyClass&gt; 继承。有什么我可以做的吗?
  • @shashwat SortFindFindAll 等可以在IEnumerable&lt;T&gt; 的LINQ 方面实现,所以这不是问题。
【解决方案5】:
class Animals : List<Animal> {}

似乎是最好的方式,因为你可以在这样定义之后使用它。

所以我的建议是你的问题标题:Inherit List&lt;T&gt; ;-)

【讨论】:

【解决方案6】:

不必从List 继承来使用集合初始化语法或使用Linq 扩展方法。

只需实现IEnumerableAdd 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-03
    • 2011-07-09
    • 2023-03-30
    • 2010-10-28
    • 1970-01-01
    • 2019-02-17
    • 1970-01-01
    • 2010-10-22
    相关资源
    最近更新 更多