.net List (of T) 和 Collection(of T) 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/398903/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 10:54:08  来源:igfitidea点击:

What is the difference between List (of T) and Collection(of T)?

.netlistcollections

提问by Anthony Potts

I've seen them used in a lot of the same ways, and I am worried I'm about to go down a path in design that is irreversible if I don't understand this better. Also, I am using .NET.

我已经看到它们以很多相同的方式使用,我担心如果我不能更好地理解这一点,我将在设计中走上一条不可逆转的道路。另外,我正在使用 .NET。

采纳答案by Adam Lassek

Collection<T>is a customizable wrapper around IList<T>. While IList<T>is not sealed, it doesn't provide any customization points. Collection<T>'s methods are by default delegated to the standard IList<T>methods, but can be easily overridden to do what you want. It is also possible to wireup events inside a Collection<T>that I don't believe could be done with an IList.

Collection<T>是围绕IList<T>. 虽然IList<T>不是密封的,但它不提供任何定制点。Collection<T>的方法默认委托给标准IList<T>方法,但可以轻松覆盖以执行您想要的操作。也可以在Collection<T>我认为无法使用 IList 完成的事件中连接事件。

In short, it's much easier to extend it after the fact, which could potentially mean a lot less refactoring.

简而言之,事后扩展它要容易得多,这可能意味着更少的重构。

回答by Ian Boyd

In C#, there are three concepts for representing a bag of objects. In order of increasing features, they are:

在 C# 中,表示一袋对象有三个概念。按照增加的功能顺序,它们是:

  • Enumerable- unordered, unmodifiable
  • Collection- can add/remove items
  • List- allows items to have an order (accessing and removing by index)
  • Enumerable- 无序,不可修改
  • 收藏- 可以添加/删除项目
  • 列表- 允许项目有顺序(按索引访问和删除)

Enumerablehas no order. You cannot add or remove items from the set. You cannot even get a count of items in the set. It strictly lets you access each item in the set, one after the other.

Enumerable没有顺序。您不能在集合中添加或删除项目。您甚至无法获得集合中的项目数。它严格允许您一个接一个地访问集合中的每个项目。

Collectionis a modifiable set. You can add and remove objects from the set, you can also get the count of items in the set. But there still is no order, and because there is no order: no way to access an item by index, nor is there any way to sort.

集合是一个可修改的集合。您可以从集合中添加和删除对象,还可以获取集合中的项目数。但是仍然没有顺序,因为没有顺序:无法通过索引访问项目,也没有任何排序方法。

Listis an ordered set of objects. You can sort the list, access items by index, remove items by index.

列表是一组有序的对象。您可以对列表进行排序、按索引访问项目、按索引删除项目。

In fact, when looking at the interfaces for these, they build on one another:

事实上,当查看这些接口时,它们是相互建立的:

  • interface IEnumerable<T>

    • GetEnumeration<T>
  • interface ICollection<T> : IEnumerable<T>

    • Add
    • Remove
    • Clear
    • Count
  • interface IList<T> = ICollection<T>

    • Insert
    • IndexOf
    • RemoveAt
  • interface IEnumerable<T>

    • GetEnumeration<T>
  • interface ICollection<T> : IEnumerable<T>

    • Add
    • Remove
    • Clear
    • Count
  • interface IList<T> = ICollection<T>

    • Insert
    • IndexOf
    • RemoveAt

When declaring variables, or method parameters, you should choose to use

在声明变量,或者方法参数时,应该选择使用

  • IEnumerable
  • ICollection
  • IList
  • IEnumerable
  • 收藏
  • 列表

based on conceptually you need to do with the set of objects.

基于概念上,您需要处理对象集。

If you just need to be able to do something to every object in a list, then you only need IEnumerable:

如果您只需要能够对列表中的每个对象执行某些操作,那么您只需要IEnumerable

void SaveEveryUser(IEnumerable<User> users)
{
    for User u in users
      ...
}

You don't care if the Users are kept in a List<T>, Collection<T>, Array<T>or anything else. You only need the IEnumerable<T>interface.

如果用户被保存在一个你不关心List<T>Collection<T>Array<T>或其他任何东西。你只需要IEnumerable<T>接口。

If you need to be able to add, remove, or count the items in a set, then use a Collection:

如果您需要能够添加、删除或计算集合中的项目,请使用Collection

ICollection<User> users = new Collection<User>();
users.Add(new User());

If you care about a sort order, and need the order to be correct, then use a List:

如果您关心排序顺序,并且需要正确的顺序,请使用List

IList<User> users = FetchUsers(db);

In chart form:

以图表形式:

| Feature                | IEnumerable<T> | ICollection<T> | IList<T> |
|------------------------|----------------|----------------|----------|
| Enumerating items      | X              | X              | X        |
|                        |                |                |          |
| Adding items           |                | X              | X        |
| Removing items         |                | X              | X        |
| Count of items         |                | X              | X        |
|                        |                |                |          |
| Accessing by index     |                |                | X        |
| Removing by indexx     |                |                | X        |
| Getting index of item  |                |                | X        |

The List<T>and Collection<T>in System.Collections.Genericare two classes that implement these interfaces; but they aren't the only classes:

List<T>Collection<T>System.Collections.Generic是实现这些接口两类:但它们不是唯一的类:

  • ConcurrentBag<T>is an ordered bag of objects (IEnumerable<T>)
  • LinkedList<T>is a bag where you are not allowed to access items by index (ICollection); but you can arbitrarily add and remove items from the collection
  • SynchronizedCollection<T>in an ordered collection, where you can add/remove items by index
  • ConcurrentBag<T>是一个有序的对象包 ( IEnumerable<T>)
  • LinkedList<T>是一个包,您不能通过索引 ( ICollection)访问其中的项目;但您可以任意添加和删除集合中的项目
  • SynchronizedCollection<T>在有序集合中,您可以在其中按索引添加/删除项目

So you can easily change:

因此,您可以轻松更改:

IEnumerable<User> users = new SynchronizedCollection<User>();

SaveEveryUser(users);

tl;dr

tl;博士

  • Enumerable- access items, unordered, unmodifiable
  • Collection- can be modified (add,delete,count)
  • List- can access by index
  • Enumerable- 访问项,无序,不可修改
  • 集合- 可以修改(添加、删除、计数)
  • 列表- 可以通过索引访问

Choose the conceptyou need, then use the matching class.

选择您需要的概念,然后使用匹配的类。

回答by Arnold Zokas

List<T>is intended for internal use within the application code. You should avoid writing public APIs that accept or return List<T>(consider using a superclass or a collection interface instead).

List<T>旨在供应用程序代码内部使用。您应该避免编写接受或返回的公共 API List<T>(考虑使用超类或集合接口)。

Collection<T>serves a base class for custom collections (although it can be used directly).

Collection<T>为自定义集合提供基类(尽管它可以直接使用)。

Consider using Collection<T>in your code unless there are specific features of List<T>that you need.

Collection<T>除非有List<T>您需要的特定功能,否则请考虑在您的代码中使用。

The above are just recommendations.

以上只是建议。

[Adapted from: Framework Design Guidelines, Second Edition]

[改编自:框架设计指南,第二版]

回答by Marc Gravell

List<T>is a very commonly seen container, because it is so very versatile (with lots of handy methods like Sort, Find, etc) - but has no extension points if you want to override any of the behaviour (check items on insert, for example).

List<T>是一个非常常见的容器,因为它非常通用(有很多方便的方法,如Sort,Find等) - 但如果您想覆盖任何行为(例如,检查插入项),则没有扩展点。

Collection<T>is a wrapper around any IList<T>(defaulting to List<T>) - it has the extension points (virtualmethods), but not as many support methods like Find. Because of the indirection, it is slightly slower than List<T>, but not by much.

Collection<T>是任何IList<T>(默认为List<T>)的包装器- 它具有扩展点(virtual方法),但没有像Find. 由于间接性,它比 稍慢List<T>,但相差不大。

With LINQ, the extra methods in List<T>become less important, since LINQ-to-Objects tends to provide them anyway... for example First(pred), OrderBy(...), etc.

随着LINQ,额外的方法List<T>变得不那么重要,因为LINQ到对象往往反正他们提供...例如First(pred)OrderBy(...)等等。

回答by tuinstoel

List is faster.

列表更快。

Do for example

做例如

private void button1_Click(object sender, EventArgs e)
{
  Collection<long> c = new Collection<long>();
  Stopwatch s = new Stopwatch();
  s.Start();
  for (long i = 0; i <= 10000000; i++)
  {
    c.Add(i);
  }
  s.Stop();
  MessageBox.Show("collect " + s.ElapsedMilliseconds.ToString());

  List<long> l = new List<long>();
  Stopwatch s2 = new Stopwatch();
  s2.Start();
  for (long i = 0; i <= 10000000; i++)
  {
    l.Add(i);
  }
  s2.Stop();
  MessageBox.Show("lis " + s2.ElapsedMilliseconds.ToString());


}

on my machine List<>is almost twice as fast.

在我的机器List<>上几乎快两倍。

Edit

编辑

I can't understand why people are downvoting this. Both on my work machine and my home machine the List<> code is 80% faster.

我不明白为什么人们会反对这一点。在我的工作机器和我的家用机器上, List<> 代码都快了 80%。

回答by Manu

List represents a collection where the order of items is important. It also supports methods s.a. Sort and search. Collection is a more general data-structure which makes less assumptions about the data and also supports less methods to manipulate it. If you want to expose a custom data structure, you should probably extend the collection. If you need to manipulate data w/o exposing the data-structure, a list is probably the more convenient way to go.

List 表示一个集合,其中项目的顺序很重要。它还支持排序和搜索方法。集合是一种更通用的数据结构,它对数据的假设较少,也支持较少的操作方法。如果要公开自定义数据结构,则可能应该扩展集合。如果您需要在不公开数据结构的情况下操作数据,那么列表可能是更方便的方法。

回答by Charlie Martin

This is one of those grad school questions. A Collection of T is sort of abstract; there may be a default implementation (I'm not a .net/c# guy) but a collection will have basic operations like add, remove, iterate, and so on.

这是研究生院的问题之一。T 的集合有点抽象;可能有一个默认实现(我不是 .net/c# 人),但集合将具有基本操作,如添加、删除、迭代等。

List of T implies some specifics about these operations: add should take constant time, remove should take time proportional to the number of elements, getfirst should be consant time. In general, a List is a kind of Collection, but a Collection isn't necessarily a kind of List.

T 的列表暗示了这些操作的一些细节:添加应该花费常数时间,删除应该花费与元素数量成正比的时间,getfirst 应该是常数时间。一般来说,List是一种Collection,但Collection不一定是一种List。

回答by Raj Gupta

All of these interfaces inherit from IEnumerable, which you should make sure you understand. That interface basically lets you use the class in a foreach statement (in C#).

所有这些接口都继承自IEnumerable,您应该确保您理解它们。该接口基本上允许您在 foreach 语句(在 C# 中)中使用该类。

  • ICollectionis the most basic of the interfaces you listed. It's an enumerable interface that supports a Countand that's about it.
  • IListis everything that ICollectionis, but it also supports adding and removing items, retrieving items by index, etc. It's the most commonly-used interface for "lists of objects", which is vague I know.
  • IQueryableis an enumerable interface that supports LINQ. You can always create an IQueryablefrom an IList and use LINQ to Objects, but you also find IQueryableused for deferred execution of SQL statements in LINQ to SQL and LINQ to Entities.
  • IDictionaryis a different animal in the sense that it is a mapping of unique keys to values. It is also enumerable in that you can enumerate the key/value pairs, but otherwise it serves a different purpose than the others you listed
  • ICollection是您列出的最基本的接口。它是一个支持 a 的可枚举接口,仅Count此而已。
  • IList就是一切ICollection,但它还支持添加和删除项目、按索引检索项目等。它是“对象列表”最常用的接口,我知道这很模糊。
  • IQueryable是一个支持 LINQ 的可枚举接口。您始终可以IQueryable从 IList创建一个并使用 LINQ to Objects,但您也发现IQueryable用于延迟执行 LINQ to SQL 和 LINQ to Entities 中的 SQL 语句。
  • IDictionary是一种不同的动物,因为它是唯一键到值的映射。它也是可枚举的,因为您可以枚举键/值对,但除此之外,它的用途与您列出的其他用途不同

回答by Tom

According to MSDN, List(Of T).Add is "an O(n) operation" (when "Capacity" is exceeded) while Collection(Of T).Add is always"an O(1) operation". That would understandable if List is implemented using an Array and Collection a Linked List. However, if that were the case, one would expect Collection(Of T).Item to be "an O(n) operation". But - it's - not!?! Collection(Of T).Item is "an O(1) operation" just like List(Of T).Item.

根据 MSDN,List(Of T).Add 是“O(n) 操作”(当超过“容量”时),而 Collection(Of T).Add总是“O(1) 操作”。如果 List 是使用 Array 和 Collection a Linked List 实现的,那将是可以理解的。但是,如果是这种情况,人们会期望 Collection(Of T).Item 是“O(n) 操作”。但是——它是——不是!?!Collection(Of T).Item 是“O(1) 操作”,就像 List(Of T).Item 一样。

On top of that, "tuinstoel"'s "Dec 29 '08 at 22:31" post above claims speed tests show List(Of T).Add to be faster than Collection(Of T).Add which I've reproduced with Long's and String's. Although I only got ~33% faster vs. his claimed 80%, according MSDN, it should've been the opposite and by "n" times!?!

最重要的是,“tuinstoel”的“2008 年 12 月 29 日 22:31”帖子声称速度测试显示 List(Of T).Add 比 Collection(Of T).Add 快,我用它复制了长的和字符串的。尽管我只比他声称的 80% 快了大约 33%,但根据 MSDN,它应该是相反的,并且是“n”倍!?!

回答by Tad Donaghe

Hanselman Speaks: "Collection<T>looks like a list, and it even has a List<T>internally. EVERY single method delegates to the internal List<T>. It includes a protected property that exposes the List<T>."

Hanselman 说:“Collection<T>看起来像一个列表,它甚至在List<T>内部有一个。每个方法都委托给内部List<T>。它包括一个公开的受保护的属性List<T>。”

EDIT: Collection<T>doesn't exist in System.Generic.Collections .NET 3.5. If you migrate from .NET 2.0 to 3.5 you'll need to change some code if you're using a lot of Collection<T>objects, unless I'm missing something obvious...

编辑: Collection<T>在 System.Generic.Collections .NET 3.5 中不存在。如果您从 .NET 2.0 迁移到 3.5,如果您使用了大量Collection<T>对象,则需要更改一些代码,除非我遗漏了一些明显的东西...

EDIT 2: Collection<T>is now in the System.Collections.ObjectModel namespace in .NET 3.5. The help file says this:

编辑 2:Collection<T>现在位于 .NET 3.5 中的 System.Collections.ObjectModel 命名空间中。帮助文件是这样说的:

"The System.Collections.ObjectModel namespace contains classes that can be used as collections in the object model of a reusable library. Use these classes when properties or methods return collections."

“System.Collections.ObjectModel 命名空间包含可用作可重用库的对象模型中的集合的类。当属性或方法返回集合时使用这些类。”