使用IEnumerable vs ICollection vs IList创建自定义集合

28

我需要设计自己的定制化GenericCollection类。现在我有很多选项可以使用IEnumerableICollectionIList进行推导,后者提供了一些附加功能。

如果我使用IEnumerable<T>,我可能需要声明实际保存集合的对象,比如在这个例子中的_list,这让我有点困惑。

public class GenericCollection<T> : IEnumerable<T>
{
    private List<T> _list;
    //...
}

但是如果我使用ICollection<T>或者IList<T>,我就不需要声明List对象,因为它会被隐式地提供。

public class GenericCollection<T> : IList<T>
{
    // no need for List object
    //private List<T> _list; 
    //...
}
这两种方法在性能方面有什么区别?
在设计自己的集合时,每种情况下都应该选择哪个?我想使用IEnumerable<T>来实现轻量级集合和良好性能,但具体如何以及一些强烈理由是什么?
我查看了一些现有的帖子,但没有提供所需的信息。 返回'IList' vs 'ICollection' vs 'Collection'

在第一个例子中,您不需要在列表成员中有"_list"。而且,如果从IList继承并实现公共接口,则仍然需要实现一些存储机制。 - Ilya Ivanov
通用集合?听起来像是一个列表... - Storm Muller
你可以更改底层实现,泛型集合只是一个包装器。 - Furqan Safdar
3个回答

70

IEnumerableICollectionIList(通常是任何带有I前缀的类型)只是接口。它们让您暴露类将要执行的操作,但与继承类不同,接口不会为您提供任何必须执行的默认实现。

至于选择哪个接口,这里是一个快速指南:

  • IList是可以通过索引访问的ICollection
  • ICollection是具有易于访问AddRemoveCount等内容的IEnumerable
  • IEnumerable是任何可枚举的东西,即使这些东西的列表在枚举之前不存在。

您可能希望扩展一些类(或将其保留为私有字段,以运行大部分逻辑)来管理集合,例如List<T>Collection<T>(它实现了IList<T>,但具有更容易覆盖实现的访问权限。请参阅Collection<T> versus List<T> what should you use on your interfaces?,了解这两者之间的重大区别),ObservableCollection<T>,或不是列表的集合,如Dictionary<T, U>HashSet<T>。有关任何这些类的更多信息,请查阅MSDN文档。


1
首先,你不必在这些接口之间进行选择,如果有必要,你可以实现所有三个接口。其次,实现IEnumerable不需要你将底层列表公开。你只需实现使用底层列表的枚举器的方法即可。
就性能而言,我怀疑不会有太大的影响,重点是关注你需要的功能。唯一确定的方法是进行测量。

我错误地添加了public List,谢谢您指出。实现这三个接口的用途是什么?如果我只关注功能,则可以使用带有添加和准备好的功能的List<T>。但是,我正在寻找一些强有力的理由选择IEnumerable<T>,如果有的话? - Furqan Safdar
既然IList实现了IEnumerable,如果你实现了IList,就不需要显式地实现它。我只是想说这不是一个非此即彼的问题。 - Rik

0

性能不太可能依赖于实现哪些接口,而更取决于处理器运行多少指令才能达到特定目标。如果您实现IEnumerable并在List上进行包装,则很可能最终编写Add/Remove/this[]方法只是将调用传播到List,这会增加性能开销。因此,尽管我没有进行任何测量,但继承方法可能会快一点。

然而,这些细节通常只对实时应用程序具有极端的需要节省每个可能的CPU周期的情况下才有影响。Eric Lippert有一篇关于注意此类细节的好文章:http://blogs.msdn.com/b/ericlippert/archive/2003/10/17/53237.aspx。通常,您最好使用更适合业务逻辑和应用程序架构的方法,而不是性能细节。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接