返回“IList”与“ICollection”与“Collection”

我很困惑我应该从我的公共API方法和属性返回哪个集合types。

我脑海中的collections品是IListICollectionCollection

返回这些types之一总是优于其他types,还是取决于具体情况?

一般来说,您应该返回一个尽可能通用的types,即只知道消费者需要使用的返回数据的types。 这样,您可以更自由地更改API的实现,而不会破坏正在使用它的代码。

还要考虑IEnumerable<T>接口作为返回types。 如果结果只是迭代,消费者不需要更多。

ICollection<T>是一个暴露集合语义的接口,如Add()Remove()Count

Collection<T>ICollection<T>接口的具体实现。

IList<T>本质上是一个ICollection<T>具有随机的基于顺序的访问。

在这种情况下,您应该决定您的结果是否需要列表语义,如基于命令的索引(然后使用IList<T> ),或者您是否需要返回无序的“bag”结果(然后使用ICollection<T> )。

IList<T>ICollection<T>之间的主要区别在于IList<T> IList<T>允许您通过索引访问元素。 IList<T>描述了类似数组的types。 ICollection<T>中的元素只能通过枚举访问。 两者都允许插入和删除元素。

如果您只需要枚举集合,那么使用IEnumerable<T>是首选。 它有两个优点:

  1. 它禁止更改集合(但不包括引用的对象,如果元素是引用)。

  2. 它允许尽可能多的来源,包括algorithm生成的枚举,而不是集合。

Collection<T>是一个基本类,主要用于集合的实现者。 如果你在接口(APIs)中公开它,那么许多有用的集合将被排除在外。


IList<T>一个缺点是数组实现它,但不允许你添加或删除项目(即你不能改变数组的长度)。 如果在数组上调用IList<T>.Add(item) ,将抛出exception。 由于IList<T>具有一个布尔属性IsReadOnly ,您可以在尝试这样做之前检查这种情况。 但在我看来,这仍然是图书馆的devise缺陷 。 因此,当需要添加或移除项目的可能性时,我直接使用List<T>

IList<T>是所有通用列表的基本接口。 由于它是一个有序的集合,所以实现可以决定sorting顺序,从sorting顺序到sorting顺序。 此外, Ilist Item属性允许方法根据索引读取和编辑列表中的条目。 这使得可以在位置索引处插入/从列表中删除值。

另外,由于IList<T> : ICollection<T>IList<T> : ICollection<T>中的所有方法也可在此处实现。

ICollection<T>是所有generics集合的基本接口。 它定义了大小,枚举器和同步方法。 您可以添加或删除一个项目到一个集合中,但是由于没有索引属性,您不能select在哪个位置发生。

Collection<T>IList<T>IListIReadOnlyList<T>提供了一个实现。

如果使用较窄的接口types(例如ICollection<T>而不是IList<T> ,则可以保护代码免受重大更改的影响。 如果使用更宽的接口types(如IList<T> ,则更有可能破坏代码更改。

引用来源 ,

ICollectionICollection<T> :您想要修改集合或关心其大小。 IListIList<T> :您想要修改集合,并关心集合中元素的sorting和/或位置。

返回一个接口types更一般,所以(缺乏关于你的具体用例的进一步的信息)我会倾向于这个。 如果要公开索引支持,请selectIList<T> ,否则ICollection<T>就足够了。 最后,如果要指示返回的types是只读的,请selectIEnumerable<T>

而且,如果您还没有阅读过,Brad Abrams和Krzysztof Cwalina写了一本名为“Framework Design Guidelines:Conventions,Idioms,and Patterns for Reusable .NET Libraries”的书(可以从这里下载摘要)。

有一些问题来自这个问题:

  • 接口与类
  • 哪些具体的类,从几个相似的类,集合,列表,数组?
  • 普通类与子类(“generics”)集合

您可能需要强调其面向对象的API

接口与类

如果你没有太多接口的经验,我build议坚持上课。 我看到很多开发人员跳入界面,即使它不是必需的。

而且,最终做的糟糕的界面devise,而不是一个好的类devise,顺便说一句,最终可以迁移到一个良好的界面devise…

你会在API中看到很多接口,但是,如果你不需要的话,不要急于接受它。

您最终将学习如何将接口应用于您的代码。

哪些具体的类,从几个相似的类,集合,列表,数组?

c#(dotnet)中有几个类可以互换。 如前所述,如果您需要更具体的类(如“CanBeSortedClass”),请在API中明确指定。

你的API用户是否真的需要知道,你的类可以被sorting,或者对这些元素应用某种格式? 然后使用“CanBeSortedClass”或“ElementsCanBePaintedClass”,否则使用“GenericBrandClass”。

否则,使用更普通的类。

通用集合类与子类(“generics”)集合

您会发现有些类包含其他元素,您可以指定所有元素应该是特定的types。

generics集合是那些可以使用相同集合的类,对于多个代码应用程序,无需为每个新子types创build新集合,如下所示: Collection

你的API用户是否需要一个非常特定的types,对于所有的元素都是一样的?

使用像List<WashingtonApple>东西。

你的API用户是否需要几种相关的types?

公开List<Fruit>为您的API,并使用List<Orange> List<Banana>List<Strawberry>内部,其中OrangeBananaStrawberryFruit后代。

你的API用户是否需要一个genericstypes集合?

使用List ,其中所有项目都是object

干杯。