【问题标题】:Prefer Inheritance or Containment when creating specialized collections?在创建专门的集合时更喜欢继承还是包含?
【发布时间】:2009-08-19 21:31:00
【问题描述】:

我需要专门的集合类。我们称它们为 FooItems 和 BarItems。

我基本上需要 List 的所有功能,但是当从集合中添加或删除新项目时,我需要做一些额外的工作。

我的第一个尝试是简单地从 List 和 List 派生,然后创建我自己的 Add 和 Remove 方法。这当然会创建一个隐藏副作用的函数,编译器建议使用“new”关键字来显式隐藏基类。

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

不过,这感觉很臭。如果有人通过 List 或 IList 引用引用 FooCollection,这可能会导致问题,因为它不会调用我的(非虚拟)Add 函数,而是调用 List 版本。

当然,在我当前的代码中,这不太可能发生……但我们永远无法预测未来。

当然,另一种选择是重新实现 IList 接口并包含 List,但是这很容易违反 DRY(而且工作量很大,尤其是对于多个集合)。

我已经倾向于将收容作为首选方法。只是想知道是否有人对此有一些意见。

【问题讨论】:

    标签: c# generics inheritance containers


    【解决方案1】:

    在这种情况下更喜欢组合。

    您应该实现IList&lt;T&gt;,但切勿在任何公共API 中直接(包括通过继承)公开List&lt;T&gt;。它应该是一个实现细节。

    【讨论】:

      【解决方案2】:

      我同意这种气味,并建议收容。如果您需要IList&lt;T&gt; 中的所有功能,那么就保持简单而言,您可能不走运。你可以改用ICollection&lt;T&gt;吗?

      已编辑如果您需要多次执行此操作,您始终可以使用虚拟实现创建 MyList&lt;T&gt; : IList&lt;T&gt;。至少那时你只实现了一次接口的大部分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-27
        • 2015-06-13
        • 1970-01-01
        • 2012-01-15
        • 2012-09-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多