简体   繁体   English

创建专门的集合时是首选继承还是包含?

[英]Prefer Inheritance or Containment when creating specialized collections?

I have a need for specialized collection classes. 我需要专门的收藏课。 Let's call them FooItems and BarItems. 我们称它们为FooItems和BarItems。

I basically need all the functionality of a List, but I need to do some extra work when new items are added or removed from the collection. 我基本上需要列表的所有功能,但是当从集合中添加或删除新项目时,我需要做一些额外的工作。

My first stab at this was to simply derive from List and List, then create my own Add and Remove methods. 我的第一个方法是简单地从List和List派生,然后创建自己的Add和Remove方法。 This of course creates a function hiding side-effect, and the compiler suggests using the "new" keyword to explictly hid the base classes. 当然,这会创建一个隐藏副作用的函数,并且编译器建议使用“ new”关键字来显式隐藏基类。

public class FooCollection : List<Foo>
{
    public new void Add(Foo foo)
    {
        // Do my work then...
        base.Add(foo);
    }
}

This feels smelly though. 不过,这感觉很臭。 This can cause problems if someone references the FooCollection via a List or IList reference, since it won't call my (non-virtual) Add function, but rather the List version. 如果有人通过List或IList引用引用FooCollection,则可能导致问题,因为它不会调用我的(非虚拟)Add函数,而是调用List版本。

Of course in my current code, that's not likely to happen... but one can never predict the future. 当然,在我当前的代码中,这不太可能发生……但是人们永远无法预测未来。

The other option, of course, is to re-implement the IList Interface and contain the List, but that stinks of DRY violation (and It's also a lot of work, especially for multiple collections). 当然,另一种选择是重新实现IList接口并包含List,但是这会违反DRY(这也是很多工作,尤其是对于多个集合)。

I am already leaning towards containment as the preferred method.. just wondering if anyone else has some input on this. 我已经倾向于将遏制作为首选方法..我只是想知道是否有人对此有所投入。

Prefer composition in this case. 在这种情况下,最好选择成分。

You should implement IList<T> , but never expose List<T> directly (including via inheritance) in any public API. 您应该实现IList<T> ,但绝对不要在任何公共API中直接公开List<T> (包括通过继承)。 It should be an implementation detail. 它应该是一个实现细节。

I agree about the smell, and recommend containment. 我同意这种气味,并建议采取收容措施。 If you need all of the functionality in IList<T> , you're probably out of luck as far as keeping it simple is concerned. 如果您需要IList<T>所有功能,那么就保持简单而言可能就不走运了。 Can you use, say, ICollection<T> instead? 您可以改用ICollection<T>吗?

EDITED If you need to do this several times over, you can always create MyList<T> : IList<T> with virtual implementations. 编辑如果需要多次执行此操作,则始终可以使用虚拟实现创建MyList<T> : IList<T> At least then you're implementing the majority of the interface just once. 至少您只需一次实现大部分接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM