我已经看到它们以很多相同的方式使用了,我担心如果我不能更好地理解这一点,我将要走上一条不可逆转的设计之路.另外,我正在使用.NET.
在C#中,有三个概念用于表示一包对象.为了增加功能,它们是:
可枚举 - 无序,不可修改
收藏 - 可以添加/删除项目
列表 - 允许项目拥有订单(按索引访问和删除)
可枚举没有订单.您无法在集中添加或删除项目.你甚至无法获得集合中的项目数.它严格允许您一个接一个地访问集合中的每个项目.
集合是一个可修改的集合.您可以在集合中添加和删除对象,也可以获取集合中的项目数.但是仍然没有订单,因为没有订单:无法按索引访问项目,也没有任何方法可以排序.
List是一组有序的对象.您可以对列表进行排序,按索引访问项目,按索引删除项目.
实际上,在查看这些接口时,它们会相互构建:
interface IEnumerable
GetEnumeration
interface ICollection
Add
Remove
Clear
Count
interface IList
Insert
IndexOf
RemoveAt
在声明变量或方法参数时,您应该选择使用
IEnumerable的
ICollection的
IList的
基于概念,您需要处理对象集.
如果您只需要能够对列表中的每个对象执行某些操作,那么您只需要IEnumerable
:
void SaveEveryUser(IEnumerableusers) { for User u in users ... }
如果用户被保存在一个你不关心List
,Collection
,Array
或其他任何东西.你只需要IEnumerable
界面.
如果您需要能够添加,删除或计算集合中的项目,请使用集合:
ICollectionusers = new Collection (); users.Add(new User());
如果您关心排序顺序,并且需要订单正确,那么请使用List:
IListusers = FetchUsers(db);
以图表形式:
| Feature | IEnumerable| ICollection | IList | |------------------------|----------------|----------------|----------| | 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 |
在List
和Collection
在System.Collections.Generic
是实现这些接口两类:但他们不是唯一的课程:
ConcurrentBag
是一个有序的对象袋(IEnumerable
)
LinkedList
是一个不允许您通过索引(ICollection
)访问项目的包; 但您可以随意添加和删除集合中的项目
SynchronizedCollection
在有序集合中,您可以通过索引添加/删除项目
所以你可以轻松改变:
IEnumerableTL;博士users = new SynchronizedCollection (); SaveEveryUser(users);
可枚举 - 访问项目,无序,不可修改
收藏 - 可以修改(添加,删除,计数)
列表 - 可以通过索引访问
选择您需要的概念,然后使用匹配的类.
Collection
是一个可定制的包装器IList
.虽然IList
没有密封,但它没有提供任何定制点.Collection
默认情况下,方法被委托给标准IList
方法,但可以轻松覆盖以执行您想要的操作.也可以将事件中的事件连接Collection
到我认为不能用IList完成的事件中.
简而言之,在事实之后扩展它会容易得多,这可能意味着更少的重构.
List
适用于应用程序代码中的内部使用.您应该避免编写接受或返回的公共API List
(请考虑使用超类或集合接口).
Collection
为自定义集合提供基类(尽管可以直接使用).
Collection
除非有List
您需要的特定功能,否则请考虑在您的代码中使用.
以上只是建议.
[改编自:框架设计指南,第二版]
List
是一个非常常见的容器,因为它非常通用(有许多方便的方法,如Sort
,Find
等) - 但如果你想覆盖任何行为(例如,检查插入项目),则没有扩展点.
Collection
是任何IList
(默认为List
)的包装- 它有扩展点(virtual
方法),但没有那么多的支持方法Find
.由于间接性,它略微慢List
,但不是很多.
随着LINQ,额外的方法List
变得不那么重要,因为LINQ到对象往往为他们提供反正...例如First(pred)
,OrderBy(...)
等等.
列表更快.
举个例子
private void button1_Click(object sender, EventArgs e) { Collectionc = new Collection (); 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 l = new List (); Stopwatch s2 = new Stopwatch(); s2.Start(); for (long i = 0; i <= 10000000; i++) { l.Add(i); } s2.Stop(); MessageBox.Show("lis " + s2.ElapsedMilliseconds.ToString()); }
在我的机器List<>
上几乎快两倍.
编辑
我无法理解为什么人们会贬低这一点.在我的工作机器和家用机器上,List <>代码的速度提高了80%.
List表示项目顺序很重要的集合.它还支持排序和搜索方法.集合是一种更通用的数据结构,它对数据的假设较少,并且支持较少的操作方法.如果要公开自定义数据结构,则应该扩展该集合.如果您需要操作数据而不暴露数据结构,列表可能是更方便的方法.