IEnumerable和List有啥区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IEnumerable和List有啥区别相关的知识,希望对你有一定的参考价值。

两者区别有如下几点1、一个Collection要支持foreach方式的遍历,必须实现IEnumerable接口(亦即,必须以某种方式返回IEnumerator object)。

2、IEnumerator object具体实现了iterator(通过MoveNext(),Reset(),Current)。

3、从这两个接口的用词选择上,也可以看出其不同:IEnumerable是一个声明式的接口,声明实现该接口的class是“可枚举(enumerable)”的,但并没有说明如何实现枚举器(iterator);IEnumerator是一个实现式的接口,IEnumerator object就是一个iterator。

4、IEnumerable和IEnumerator通过IEnumerable的GetEnumerator()方法建立了连接,client可以通过IEnumerable的GetEnumerator()得到IEnumerator object,在这个意义上,将GetEnumerator()看作IEnumerator object的factory method也未尝不可。
IEnumerator 是所有枚举数的基接口。

枚举数只允许读取集合中的数据。枚举数无法用于修改基础集合。

最初,枚举数被定位于集合中第一个元素的前面。Reset 也将枚举数返回到此位置。在此位置,调用 Current 会引发异常。因此,在读取 Current 的值之前,必须调用 MoveNext 将枚举数提前到集合的第一个元素。

在调用 MoveNext 或 Reset 之前,Current 返回同一对象。MoveNext 将 Current 设置为下一个元素。

在传递到集合的末尾之后,枚举数放在集合中最后一个元素后面,且调用 MoveNext 会返回 false。如果最后一次调用 MoveNext 返回 false,则调用 Current 会引发异常。若要再次将 Current 设置为集合的第一个元素,可以调用 Reset,然后再调用 MoveNext。

只要集合保持不变,枚举数就将保持有效。如果对集合进行了更改(例如添加、修改或删除元素),则该枚举数将失效且不可恢复,并且下一次对 MoveNext 或 Reset 的调用将引发 InvalidOperationException。如果在 MoveNext 和 Current 之间修改集合,那么即使枚举数已经无效,Current 也将返回它所设置成的元素。

枚举数没有对集合的独占访问权;因此,枚举一个集合在本质上不是一个线程安全的过程。甚至在对集合进行同步处理时,其他线程仍可以修改该集合,这会导致枚举数引发异常。若要在枚举过程中保证线程安全,可以在整个枚举过程中锁定集合,或者捕捉由于其他线程进行的更改而引发的异常。
参考技术A 如下
IList接口可以使用更多的方法。比如你看一个集合是否包含相应实体,IEnumerable不行,而IList里有Contains,相应的实现了IList的可以添加,删除相应实体。而IEnumerable不行。
但是这不是说IList就比IEnumerable好,就是因为IList实现的功能多,相对来说限制大了。你看Object,任何类都可用作Object,这就是因为他简单。同理,能为IList表达的数据集,一定能为IEnumerable表达,而能为IEnumerable表达不一定能为IList表达。你可以想想Linq To Object里的方法为什么是对IEnumerable接口了而不是选择IList接口。
性能对于我们来说不是问题,就算是问题,你问的性能是什么?是IEnumerable得到Current快还是什么的?
那么我想说,这是接口,他本身没有实现,怎么比较性能,就算有,也是List<T>之类的类才会有的。
public interface IEnumerable

IEnumerator GetEnumerator();

public interface IEnumerator

bool MoveNext();
object Current get;
void Reset();

public interface IList : ICollection, IEnumerable

// Methods
int Add(object value);
void Clear();
bool Contains(object value);
int IndexOf(object value);
void Insert(int index, object value);
void Remove(object value);
void RemoveAt(int index); // Properties
bool IsFixedSize get;
bool IsReadOnly get;
object this[int index] get; set;

数据结构List和Graph有啥区别?

【中文标题】数据结构List和Graph有啥区别?【英文标题】:What's the difference between the data structure List and Graph?数据结构List和Graph有什么区别? 【发布时间】:2015-04-18 12:46:07 【问题描述】:

我知道单链表是由节点组成的,其中每个节点都有一个指向下一个节点的指针(或 null 结束列表),但图也有带有数据的节点和指向下一个节点的指针。

那么数据结构Linked List和Graph的本质区别是什么?那么基于 List 的搜索和基于 Graph 的搜索呢?

【问题讨论】:

一个图将有 多个 指向其他节点的指针(假设这是您存储图的方式)。 @Sneftel 当我有带循环的链表时,该链表将是一个图? 所有链表都是图。 没错。列表和树只是两种特殊的图形。你可以用节点和指针(顶点和边)制作的所有东西都是一个图。 @Anatoly 如果我们的答案不能满足您的需求,请告诉我们缺少什么以及您不满意的原因,但如果令人满意,请不要忘记投票并将其标记为答案,以便其他有类似情况的人问题知道这就是答案 【参考方案1】:

这不是真的,链表的节点中也有数据!(为什么你想要一个没有任何信息的节点列表?),实际上从数学的角度来看,链表是某种图形.

图和链表的主要区别在于链表中的一个节点最多有两个指针(一个指向下一个,一个指向上一个节点),但图中的一个节点可能有多个超过两个指针

【讨论】:

【参考方案2】:

链表是计算机科学中的数据结构,图是数学抽象。链表是图的可能实现之一。您始终可以以不同的方式实现图形。例如,具有 n 个顶点的图可以实现为数组 [n][n],其中如果数组 [i][j] 为真,则从顶点 i 到顶点 j 有一条边。也列出来。您可以保持与上一个和下一个节点的链接,或者只与其中一个节点保持链接。但它将是一个链接到另一个节点的节点,因为它是链表的定义。图的定义并没有说明如何将它保存在计算机程序中。

【讨论】:

【参考方案3】:

链表和图有相似之处,但链表节点是刚性的。 链表的节点具有预定义的结构,但图中的节点没有预定义的结构,例如,图的一个节点可以与另一个节点有任意数量的连接,但列表节点具有预定义的连接。列表节点只能连接相同类型的节点,而图节点也可以连接不同类型的节点。

【讨论】:

以上是关于IEnumerable和List有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

C#中的IEnumable与IEnumator接口的简单理解

List<T>,ArrayList,IEnumerable的区别

IQueryable 和 IEnumerable 有啥区别 [重复]

IEnumable和yield

List 和 IEnumerable 之间的实际区别 [重复]

IQuerable与IEnumable的区别