Inheriting from List<T>
实现从List继承的新类的最快方法是什么?
1 2 3
| class Animal {}
class Animals : List<Animal> {} // (1) |
我遇到的一个问题是:通过简单地执行(1),我发现我没有从List继承任何构造函数的好处。
最后,我希望Animals的行为与List非常相似(例如,可以构造,与linq兼容)。但另外,我还希望能够添加我自己的自定义方法。
- 你说的最快是什么意思?
- 你贴的东西对我来说很好!
- 上面的代码可以做到。您需要实现任何构造函数,只需在基本调用上调用相关的构造函数(list)。您可以在"动物"类中创建任何自定义方法
- C的可能重复:列表的继承问题
如果要创建公开的动物集合,则不应继承List,而应继承Collection,并在类名中使用后缀Collection。示例:AnimalCollection : Collection。
这一点得到了框架设计指南的支持,更具体地说:
DO NOT use ArrayList, List,
Hashtable, or Dictionary in
public APIs. Use Collection,
ReadOnlyCollection,
KeyedCollection, or
CollectionBase subtypes instead. Note
that the generic collections are only
supported in the Framework version 2.0
and above.
- 我不明白我为什么要遵循这个准则。
- +1如果OP想要在列表中做一些事情,这是很有意义的。OP可以覆盖基本的方法。我真的不认为继承List的任何其他价值仅仅是为了调用您的列表类型Animal,对吗?
- @martinho fernandes和其他任何类型的API一样,它是一个指导原则,但是如果您在公共API中提供了一个类型化的集合,您可以在将来的版本中更改它,因为它是您的类型。如果你直接使用list,那么你就走运了。
- 还可以考虑使用接口,例如ICollection、IEnumerable、IDictionary等。
- @马蒂尼奥:可能是因为你不能重写添加/删除方法,而使用Collection你可以。顺便说一句,我更愿意使用内部的List来实现IList或ICollection,而不是从Collection继承……
- @Digemall:您想要重写的内容与公共API无关。如果我不想覆盖任何内容,那么添加/删除不是虚拟的这一事实就没有问题。重要的是你想让客户可以覆盖什么。@乔&;奥:好的,这很有道理。我更喜欢使用带有内部列表的接口,因为这会给您更多的灵活性。
- @马蒂尼奥:是的,你说得对……公共API不适用于实现者,而适用于用户:)
- public APIs实际上代表什么??对于开发者来说,这是FB API还是Google API??
- 我想要访问IEnumerable扩展方法,因此从list派生对我来说是最好的情况。
- @Tombeech,Collection执行IEnumerable和IEnumerable。你从List得到了什么,而你不从Collection得到什么?
- @Jo&;Oangelo我不了解他,但我最终回答了这个问题,因为我需要List.AddRange(参见stackoverflow.com/questions/1474863/addrange-to-a-collection&zwnj;&;)。为什么只有不应该从中继承的类才有这个实用方法?是否可以向任何集合添加多个元素?我觉得我遗漏了一些逻辑结构Collection和List应该对应的细微差别。
- @最好不要继承,因为它不是为扩展而设计的,但是可以让自定义集合使用包含内部列表的组合,然后公开AddRange方法。至于列表和集合之间的差异背后的原因,我不能帮你。
构造函数不与类一起继承。必须重新实现所需的构造函数。
1 2 3 4
| public class AnimalsCollection : List<Animal>
{
public AnimalsCollection(IEnumerable<Animal> animals) : base(animals) {}
} |
- 投反对票的人想说为什么?他问他为什么"没有任何建设者",这就是为什么我的答案是这样的。如果你不同意,那么留下一些反馈怎么样?
- 与托克的原因相同。但这又一次说明了为什么匿名投票失败:这只是没有帮助。
- @康拉德·鲁道夫:什么不是手术的问题?
- 请参阅: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
- @乔治·斯托克:这仍然不是OP的问题。给他一个更好的方向是很好的,但是我有点讨厌在回答这个人的实际问题之前我们必须分析每个人的方法。知道构造函数不是继承的,这本身就是一件有用的事情。
- @安德森正确的回答是:"不要这样做,而是这样做。"当有人错误地拿着枪时,你不会温柔地告诉他们,"你不应该把枪指向你的脚。"你握住他们的手,把枪从他们指向的地方移开。这样做之后,你就可以讨论是否应该让他们用枪指着自己的头。
- @安德森是的,但这里的普遍看法不是给行动组一条鱼,而是教他们钓鱼。也就是说,我不会对这个答案投反对票,我只能再说一次,匿名的反对票很糟糕。
- 老实说,我自己也面临着这个问题,我看到的所有反对这样做的论点都是雅格尼。我真的想要一个列表类,但是我想用一些扩展来修饰它,这些扩展不会破坏列表的封装。我不太可能想要实现或继承任何其他接口。从长远来看,我可能是错的,但在这种情况下,我并没有把自己画成一个角落来做这个,我可以在真正遇到这些问题之后重构。
不建议从List衍生。主要是因为这个列表不是为了扩展,而是为了性能。
如果要创建自己的特定集合,则应继承Collection。在您的情况下,它将是:
1
| class Animals : Collection<Animal> {} |
- 我按照你的建议做了,继承了埃多克斯的遗产。但是像Collection这样的问题不支持Sort、Find、FindAll这样的方法和许多更有用的方法。我得把它改成从以东王那里继承。有什么我能做的吗?
- @shashwat没有这些方法,因为Collection应该是表示任何一组项目的通用类。例如,数学集没有特定的顺序,因此无法排序。如果元素不是唯一的,那么Find可能不明确。这两种情况都应该是Collection的一部分,因此在不失去一般性的情况下,不能包括Sort和Find。虽然可能有一个ListCollection : Collection,因为这似乎是人们最常用的。
请记住,从列表继承并不像您可能需要的那样功能齐全,许多成员不是虚拟的,因此覆盖基本实现的唯一方法是使用new语法(而不是override)来隐藏它。
如果您需要开始在标准列表操作上公开自定义行为,我将在一个类型上实现所有列表接口,该类型只使用内部列表作为实际存储。
这在很大程度上取决于您的最终需求。
- 我按照你的建议做了,并且继承了埃多克斯的遗产。但是像Collection这样的问题不支持Sort、Find、FindAll这样的方法和许多更有用的方法。我得把它改成从以东王那里继承。有什么我能做的吗?
- @根据IEnumerable的linq可以实现shashwat Sort、Find、FindAll等,这不是问题。
使用集合初始化语法或使用LINQ扩展方法不需要从List继承。
只需实现IEnumerable和Add方法。
1
| class Animals : List<Animal> {} |
寻找最好的方法,因为你可以在这样定义它之后使用它。
所以我的建议是你的问题标题:Inherit List;-)
- 投反对票的人想说为什么?
- 不是不投票,但作为一般规则,您不应该从具体的集合类继承(事实上,它们应该是sealed)。更倾向于实现接口或继承抽象基类(如Collection)。
- 同意康拉德。从以东继承是你不应该做的事情之一。在堆栈溢出上讨论了数百次。
- 请参阅:stackoverflow.com/questions/3748931/&hellip;stackoverflow.com/questions/898152/&hellip;stackoverflow.com/questions/794679/&hellip;stackoverflow.com/questions/5207459/&hellip;stackoverflow.com/questions/2136213/&hellip;stackoverflow.com/questions/349904 stackoverflow.com/questions/1257214