List <T>是否保证以添加顺序返回项目?


78

是否List<T>始终保证项目将按枚举时添加的顺序返回?

更新:谢谢大家的回答,请放心。我List<T>使用.NET Reflector快速浏览了该类(应该首先应该这样做),而实际上底层存储是TT[])数组。


19
尽管我们现在已经通过实验和逆向工程确定了当前形式的List <T>确实可以保留顺序,但是如果Microsoft将其官方化并将此保证放到文档中,那将是很好的选择。有人在读这篇文章吗?
IJ肯尼迪

2
@IJKennedy effin A!这将为更多的MS文档带来帮助。+1给你。(如果可以的话,请加100)。可能有成千上万的MS开发人员花时间进行逆向工程,测试等,所有这些都是由于缺少MS的几句话。他们没有意识到吗?岁月流逝,一切都没有改变。
詹森·S

Answers:


66

该列表基于索引,新项目将始终添加到列表的末尾。您可以在某个索引处插入项目,以便下一个项目移动一个位置。

所以,是的,你可以使用它安全地这样...

List(T)类是ArrayList类的通用等效项。它使用数组实现IList(T)通用接口,该数组的大小根据需要动态增加。

可以使用整数索引访问此集合中的元素。此集合中的索引从零开始。

不保证对List(T)进行排序。您必须先对List(T)进行排序,然后再执行需要对List(T)进行排序的操作(例如BinarySearch)。

只要不修改集合,List(T)就可以同时支持多个阅读器。通过集合进行枚举本质上不是线程安全的过程。在极少数情况下,枚举与一个或多个写访问竞争,确保线程安全的唯一方法是在整个枚举期间锁定集合。要允许多个线程访问该集合以进行读写,您必须实现自己的同步。

您可以在MSDN上阅读有关它的更多信息。


1
似乎List <T>的文档未声明检索顺序与插入顺序相同。到目前为止,它的行为确实如此,但是没有记录。
Cheeso

确实是正确的,意识到这一点总是很好,并且在绝对关键的时候,不要指望它!
Sander Versluys 2009年

@Cheeso它确实保证了检索顺序。我添加了包含此详细信息的答案。
亚历克斯·安加斯

你好 您知道行为与内联初始化是否相同吗?
Gioce90年

9

是的,List<T>保证插入顺序和检索顺序,这在MSDN上有记录(以下重点是我的)。

插入

List<T>.Add 方法

将一个对象添加到的末尾List<T>

项目参数为:

要添加到末尾的List<T>对象。

List<T>.AddRange 方法

将指定集合的​​元素添加到的末尾List<T>

集合参数为:

集合,其元素应添加到的末尾List<T>

恢复

List<T>.Enumerator 结构体

最初,枚举数位于集合中第一个元素之前。在此位置,Current未定义。因此,在读取的值之前,必须调用MoveNext将枚举数前进到集合第一个元素Current

Current返回相同的对象,直到MoveNext被调用为止。MoveNext设置Current下一个元素


3
亚历克斯,我想你可能已经得出一个没有根据的结论。“集合中的第一个元素”不必与“添加到集合中的第一个元素”相同。同样与“最后一个元素”。该文档没有提到与插入顺序有关的检索顺序。
Cheeso 2014年

只是想知道,does AddRange()保留传递给它的元素的顺序,还是可以随意将其添加到内部数组的顺序随意修改?(显然,它们都将位于当前列表的末尾)
Ryan Buddicom 2015年

亚历克斯是正确的。Microsoft的Add方法专门引用列表的顺序(在本例中为end)。就像Insert方法(“指定索引”)一样。
Chalky

一旦您注意到Lists <>具有数组索引器和Insert()方法(带有索引),就很明显它们必须被排序。这两个功能都要求是这种情况。这些方法与该类的最终用户签订了一项合同,规定这些值将在指定的位置可用,除非您以后移动它们。
krowe2'3

似乎文档已更新?现在将其添加到AddRange描述中:ldocs.microsoft.com/zh-cn/dotnet/api/… >集合中元素的顺序保留在List <T>中。
Depechie


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.