C# 返回“IList”与“ICollection”与“Collection”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9855693/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Returning 'IList' vs 'ICollection' vs 'Collection'
提问by Rocky Singh
I am confused about which collection type that I should return from my public API methods and properties.
我对应该从公共 API 方法和属性返回哪种集合类型感到困惑。
The collections that I have in mind are IList, ICollectionand Collection.
我想到的集合是IList,ICollection和Collection。
Is returning one of these types always preferred over the others, or does it depend on the specific situation?
返回这些类型中的一种总是比其他类型更受欢迎,还是取决于具体情况?
采纳答案by Guffa
Generally you should return a type that is as general as possible, i.e. one that knows just enough of the returned data that the consumer needs to use. That way you have greater freedom to change the implementation of the API, without breaking the code that is using it.
通常,您应该返回一种尽可能通用的类型,即只知道消费者需要使用的返回数据的足够多的类型。这样您就可以更自由地更改 API 的实现,而不会破坏正在使用它的代码。
Consider also the IEnumerable<T>interface as return type. If the result is only going to be iterated, the consumer doesn't need more than that.
还将IEnumerable<T>接口视为返回类型。如果结果只是被迭代,消费者不需要更多。
回答by cordialgerm
ICollection<T>is an interface that exposes collection semantics such as Add(), Remove(), and Count.
ICollection<T>是暴露集合语义诸如接口Add(),Remove()和Count。
Collection<T>is a concrete implementation of the ICollection<T>interface.
Collection<T>是ICollection<T>接口的具体实现。
IList<T>is essentially an ICollection<T>with random order-based access.
IList<T>本质上是一种ICollection<T>基于随机顺序的访问。
In this case you should decide whether or not your results require list semantics such as order based indexing (then use IList<T>) or whether you just need to return an unordered "bag" of results (then use ICollection<T>).
在这种情况下,您应该决定您的结果是否需要列表语义,例如基于顺序的索引(然后使用IList<T>),或者您是否只需要返回一个无序的结果“包”(然后使用ICollection<T>)。
回答by Olivier Jacot-Descombes
The main difference between IList<T>and ICollection<T>is that IList<T>allows you to access elements via an index. IList<T>describes array-like types. Elements in an ICollection<T>can only be accessed through enumeration. Both allow the insertion and deletion of elements.
IList<T>和之间的主要区别ICollection<T>是IList<T>允许您通过索引访问元素。IList<T>描述类似数组的类型。an 中的元素ICollection<T>只能通过枚举访问。两者都允许插入和删除元素。
If you only need to enumerate a collection, then IEnumerable<T>is to be preferred. It has two advantages over the others:
如果你只需要枚举一个集合,那么IEnumerable<T>是首选。与其他产品相比,它有两个优点:
It disallows changes to the collection (but not to the elements, if they are of reference type).
It allows the largest possible variety of sources, including enumerations that are generated algorithmically and are not collections at all.
它不允许更改集合(但不允许更改元素,如果它们是引用类型)。
它允许尽可能多的来源,包括通过算法生成的枚举,根本不是集合。
Collection<T>is a base class that is mainly useful to implementers of collections. If you expose it in interfaces (APIs), many useful collections not deriving from it will be excluded.
Collection<T>是一个基类,主要对集合的实现者有用。如果您在接口 (API) 中公开它,许多不是从它派生的有用集合将被排除在外。
One disadvantage of IList<T>is that arrays implement it but do not allow you to add or remove items (i.e. you cannot change the array length). An exception will be thrown if you call IList<T>.Add(item)on an array. The situation is somewhat defused as IList<T>has a Boolean property IsReadOnlythat you can check before attempting to do so. But in my eyes, this is still a design flaw in the library. Therefore, I use List<T>directly, when the possibility to add or remove items is required.
一个缺点IList<T>是数组实现了它但不允许您添加或删除项目(即您不能更改数组长度)。如果您调用IList<T>.Add(item)数组,则会引发异常。由于IList<T>有一个布尔属性IsReadOnly,您可以在尝试这样做之前对其进行检查,因此这种情况有所缓解。但在我看来,这仍然是图书馆的设计缺陷。因此,List<T>当需要添加或删除项目的可能性时,我直接使用。
回答by Alan
Returning an interface type is more general, so (lacking further information on your specific use case) I'd lean towards that. If you want to expose indexing support, choose IList<T>, otherwise ICollection<T>will suffice. Finally, if you want to indicate that the returned types are read only, choose IEnumerable<T>.
返回接口类型更通用,因此(缺少有关您的特定用例的更多信息)我倾向于这样做。如果要公开索引支持,请选择IList<T>,否则ICollection<T>就足够了。最后,如果要指示返回的类型是只读的,请选择IEnumerable<T>。
And, in case you haven't read it before, Brad Abrams and Krzysztof Cwalina wrote a great book titled "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries" (you can download a digest from here).
而且,如果您以前没有读过它,Brad Abrams 和 Krzysztof Cwalina 写了一本名为“框架设计指南:可重用 .NET 库的约定、习语和模式”的好书(您可以从这里下载摘要)。
回答by umlcat
There are some subjects that come from this question:
有一些主题来自这个问题:
- interfaces versus classes
- which specific class, from several alike classes, collection, list, array ?
- Common classes versus subitem ("generics") collections
- 接口与类
- 哪个特定类,来自几个相似的类,集合,列表,数组?
- 公共类与子项(“泛型”)集合
You may want to highlight that its an Object Oriented A.P.I.
您可能想强调它是一个面向对象的 API
interfaces versus classes
接口与类
If you don't have much experience with interfaces, I recommend stick to classes. I see a lot of times of developers jumping to interfaces, even if its not necesarilly.
如果您对接口没有太多经验,我建议您坚持使用类。我看到很多开发人员跳到接口,即使它不是必需的。
And, end doing a poor interface design, instead of, a good class design, which, by the way, can eventually, be migrated to a good interface design ...
并且,结束做一个糟糕的界面设计,而不是一个好的类设计,顺便说一下,最终可以迁移到一个好的界面设计......
You'll see a lot of interfaces in A.P.I., but, don't rush to it, if you don't need it.
您会在 API 中看到很多接口,但是,如果您不需要它,请不要着急。
You will eventually learn how to apply interfaces, to your code.
您最终将学习如何将接口应用于您的代码。
which specific class, from several alike classes, collection, list, array ?
哪个特定类,来自几个相似的类,集合,列表,数组?
There are several classes in c# (dotnet) that can be interchanged. As already mention, if you need something from a more specific class, such as "CanBeSortedClass", then make it explicit in your A.P.I..
c# (dotnet) 中有几个类可以互换。如前所述,如果您需要更具体的类中的某些内容,例如“CanBeSortedClass”,则在您的 API 中使其明确。
Does your A.P.I. user really needs to know, that your class can be sorted, or apply some format to the elements ? Then use "CanBeSortedClass" or "ElementsCanBePaintedClass", otherwise use "GenericBrandClass".
您的 API 用户是否真的需要知道,您的类可以排序,或者对元素应用某种格式?然后使用“CanBeSortedClass”或“ElementsCanBePaintedClass”,否则使用“GenericBrandClass”。
Otherwise, use a more general class.
否则,使用更通用的类。
Common collection classes versus subitem ("generics") collections
公共集合类与子项(“泛型”)集合
You'll find that there are classes that contains others elements, and you can specify that all elements should be of an specific type.
您会发现有些类包含其他元素,您可以指定所有元素都应属于特定类型。
Generic Collectionsare those classes that you can use the same collection, for several code applications, without having to create a new collection, for each new subitem type, like this: Collection.
通用集合是那些可以为多个代码应用程序使用相同集合的类,而无需为每个新的子项类型创建新集合,例如:Collection。
Does your A.P.I. user is going to need a very specific type, same for all elements ?
您的 API 用户是否需要一个非常特定的类型,所有元素都相同?
Use something like List<WashingtonApple>.
使用类似的东西List<WashingtonApple>。
Does your A.P.I. user is going to need several related types ?
您的 API 用户是否需要多个相关类型?
Expose List<Fruit>for your A.P.I., and use List<Orange>List<Banana>, List<Strawberry>internally, where Orange, Bananaand Strawberryare descendants from Fruit.
暴露List<Fruit>你的API,并使用List<Orange>List<Banana>,List<Strawberry>在内部,在那里Orange,Banana并Strawberry从后代Fruit。
Does your A.P.I. user is going to need a generic type collection ?
您的 API 用户是否需要泛型类型集合?
Use List, where all items are object(s).
使用List,其中所有项目都是object(s)。
Cheers.
干杯。
回答by NullReference
IList<T>is the base interface for all generic lists. Since it is an ordered collection, the implementation can decide on the ordering, ranging from sorted order to insertion order. Moreover Ilisthas Item property that allows methods to read and edit entries in the list based on their index.
This makes it possible to insert, remove a value into/from the list at a position index.
IList<T>是所有通用列表的基本接口。由于它是一个有序集合,实现可以决定排序,从排序顺序到插入顺序。此外,Ilist还有 Item 属性,允许方法根据索引读取和编辑列表中的条目。这使得可以在位置索引处向列表中插入值或从列表中删除值。
Also since IList<T> : ICollection<T>, all the methods from ICollection<T>are also available here for implementation.
此外IList<T> : ICollection<T>,来自 的所有方法ICollection<T>也可在此处实现。
ICollection<T>is the base interface for all generic collections. It defines size, enumerators and synchronization methods. You can add or remove an item into a collection but you cannot choose at which position it happens due to the absence of index property.
ICollection<T>是所有泛型集合的基本接口。它定义了大小、枚举器和同步方法。您可以在集合中添加或删除项目,但由于缺少 index 属性,您无法选择它发生的位置。
Collection<T>provides an implementation for IList<T>, IListand IReadOnlyList<T>.
Collection<T>提供IList<T>,IList和的实现IReadOnlyList<T>。
If you use a narrower interface type such as ICollection<T>instead of IList<T>, you protect your code against breaking changes. If you use a wider interface type such as IList<T>, you are more in danger of breaking code changes.
如果您使用更窄的接口类型,例如ICollection<T>代替IList<T>,您可以保护您的代码免受破坏性更改。如果您使用更广泛的接口类型,例如IList<T>,您更有可能破坏代码更改。
Quoting from a source,
引述来源,
ICollection,ICollection<T>: You want to modify the collection or you care about its size.IList,IList<T>: You want to modify the collection and you care about the ordering and / or positioning of the elements in the collection.
ICollection,ICollection<T>: 你想修改集合或者你关心它的大小。IList,IList<T>: 你想要修改集合并且你关心集合中元素的排序和/或定位。

