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

Byr*_*ahl 9 c# generics ienumerable list

或者反过来?

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

Jon*_*eet 16

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

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

  • @Marcel:请注意.`IEnumerable <T>`接口不包含改变序列的方法.具体实现可能是也可能不是可变的.如果方法签名表示它返回`IEnumerable <Whatever>`并且代码返回`List <Whatever>`,则调用代码可以很容易地将返回的对象强制转换为`List <Whatever>`并改变列表的内容.但是签名确实*表示结果应该被视为只读*. (3认同)
  • @Phil:在很多情况下,将"IEnumerable <T>"强制转换为"IList <T>"是合适的.例如,`.Last`扩展方法似乎在可能的情况下将其参数强制转换为`IList <T>`; 从而允许几乎立即检索10,000,000项目列表的最后一项,而无需阅读前9,999,999项. (3认同)

Jef*_*nal 6

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

public void DoSomething(IEnumerable<T> enumerable) {
}
Run Code Online (Sandbox Code Playgroud)

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

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

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


Der*_*eer 6

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

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

其次,IEnumerable是枚举的抽象,而List是该抽象的一个实现.遵循设计模式 - 可重用面向对象软件的元素的指导,通过允许以后更改实现而不影响消耗代码,对实现的抽象编程有助于使应用程序更具弹性.如果确实需要列表行为,则应直接公开IList而不是List.