使用List <t>而不是IEnumerable <t>?</t> </t>有什么好处

时间:2009-11-09 15:17:46

标签: c# generics list ienumerable

或者反过来?

我一直使用通用列表。但我偶尔也会听到有关IEnumerables的消息,我老实说它(今天)不知道它们是什么以及我为什么要使用它们。所以,冒着在网上有东西永远更多地宣扬我的无知的风险,我谦虚地发布这个问题。

8 个答案:

答案 0 :(得分:16)

好吧,List<T>实现IEnumerable<T> ...基本上IEnumerable<T>只是一系列项目。你可以通读它,这就是全部。

List<T>是一个可变集合 - 您可以添加它,从中删除,排序等。它本身更灵活,但IEnumerable<T>允许您使用相同的代码来处理任何实现(使用yield语句从方法返回的数组,链表,列表,迭代器等)。

答案 1 :(得分:6)

IEnumerable<T>是一个更通用的接口,因此您可以替换为您的操作实现该接口的任何内容。如果你有这个方法:

public void DoSomething(IEnumerable<T> enumerable) {
}

它将适用于数组,集合,列表,字典以及实现该接口的任何其他内容。

如果指定对象是List<T>,则该方法仅适用于List<T>个对象或从其继承的实例。

使用List<T>的优点是列表具有比枚举更多的功能。当您需要这些功能(插入,搜索,转换等)时,List<T>IList<T>更合适。

答案 2 :(得分:6)

John Skeet和其他人提供了关于List over IEnumerable的功能的一个很好的概要,所以我想我会填写问题的另一半,“使用IEnumerable而不是List有什么好处?”。 / p>

首先,IEnumerable提供了一个更通用的合约,用于表示可以迭代的事物集合,因此允许您遵守Principle of Least Privilege。换句话说,IEnumerable应该优先于其派生类型,其中枚举是需要为手头任务公开的唯一行为。这是有益的,因为暴露信息和/或行为会不必要地打开您的API,直至可能出现意外用法,这可能会造成安全问题,或者可能导致API与其消费者之间出现意外耦合。

其次,IEnumerable是枚举的抽象,而List是该抽象的一个实现。遵循Design Patterns - Elements of Reusable Object-Oriented Software的指导,通过允许实现在以后更改而不影响消耗代码,对实现的抽象编程有助于使应用程序更具弹性。如果确实需要列表行为,则应直接公开IList而不是List。

答案 3 :(得分:2)

List<T>优于IEnumerable<T>的最大优势如下

  1. 随机访问
  2. 计算属性
  3. ForEach方法
  4. 可变性
  5. 前两个在IEnumerable<T>上也很容易,但你不能保证O(1)的速度。在Count的情况下,你甚至无法保证真正的答案,因为IEnumerable<T>可以很容易地代表无限列表。

答案 4 :(得分:1)

List提供了IEnumerable之外的其他方法。您不能使用IEnumerable添加插入或删除,但您可以使用List。

当您计划仅循环数据时,应使用IEnumerable。它为您提供了优于IList的优势,因为您不必一次加载所有数据来传递对数据的访问权限,您只需要能够通过枚举器获取下一条记录。 IEnumerable也是一个接口,因此您可以“隐藏”包含数据List,Array等的实际对象的类型。

答案 5 :(得分:0)

如果您只需要在IEnumerable<T>中公开和实施的功能,那么您应该使用它。如果您希望能够迭代实现接口IEnumerable<T> where T : IFoo的对象,则替代方法是IFoo。但是,如果您需要Count之类的属性以及List<T>公开的属性,那么您应该这样做。找到最低的共同点,并使用它,因为它使您的方法更通用,更容易使用。

答案 6 :(得分:0)

IEnumerable具有干净的只读和“可枚举”或“可查询”语义。使用List看起来你允许任何人修改它:)。

答案 7 :(得分:0)

尚未提及的IEnumerable的一个优点:Contravariance。如果给出IEnumerable(Of HondaCivic),那么期望IEnumerable(Of Car)的例程将非常高兴,这反过来意味着它会对IList(Of HondaCivic)感到满意。相比之下,期望IList(Of Car)的例程将不满足IList(HondaCivic)。如果Microsoft IList是从只读的IReadableByIndex接口派生的,那么期望IReadableByIndex(Of Car)的代码对于IReadableByIndex(Of HondaCivic)非常满意,但这就是桥下的水。