English 中文(简体)
What is the benefit to using List<T> over IEnumerable<T>?
原标题:

or the other way around?

I use generic lists all the time. But I hear occasionally about IEnumerables, too, and I honestly have no clue (today) what they are for and why I should use them. So, at the risk of having something on the net forever more proclaiming my ignorance, I humbly post this question.

最佳回答

Well, List<T> implements IEnumerable<T>... basically IEnumerable<T> is just a sequence of items. You can read through it, and that s all.

List<T> is a mutable collection - you can add to it, remove from it, sort it etc. It s more flexible in itself, but IEnumerable<T> allows you to use the same code to work with any implementation (arrays, linked lists, lists, iterators returned from methods using yield statements etc).

问题回答

IEnumerable<T> is a more general interface, so you can substitute anything that implements that interface for your operation. If you have this method:

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

It will work on arrays, collections, lists, dictionaries, and anything else that implements the interface.

If you specify that the object is a List<T>, the method will only work on List<T> objects or instances that inherit from it.

The advantage of using List<T> is that lists have many more features than enumerables. When you need those features (insertion, searching, conversion, and many more), List<T> or IList<T> is more appropriate.

John Skeet and others have offered a good synopsis of the functionality of List over IEnumerable, so I thought I d fill in the other half of the question which is "What are the benefits of using IEnumerable over List?".

First, IEnumerable provides a more generic contract for representing a collection of things you can iterate over and therefore allows you to adhere to the Principle of Least Privilege. In other words, IEnumerable should be preferred over its derived types where enumeration is the only behavior that needs to be exposed for the task at hand. This is beneficial because exposing information and/or behavior unnecessarily opens your API up to possible unintended usages which can pose a security issue or can cause unintended coupling between your API and its consumers.

Second, IEnumerable is an abstraction for enumeration whereas List is one implementation of that abstraction. Following the guidance of Design Patterns - Elements of Reusable Object-Oriented Software, programming to abstractions over implementations aids in making applications more resilient to change by allowing implementations to be changed later without impacting consuming code. If you do need list behavior, you should expose IList rather than List directly.

The biggest advantages of List<T> over IEnumerable<T> are the following

  1. Random access
  2. Count property
  3. ForEach method
  4. Mutability

The first 2 are easy to do on IEnumerable<T> as well but you can t guarantee O(1) speed. In the case of Count you can t even guarantee a real answer as IEnumerable<T> can easily represent infinite lists.

List provides additional methods over IEnumerable. You can t add insert or delete with IEnumerable, but you can with List.

IEnumerable should be used when you plan on looping through the data only. It gives you an advantage over IList, because you don t have to load all the data at once to pass access to the data, you just have to be able to get the next record through the enumerator. IEnumerable is also an interface, so you can "hide" the type of the actual object containing the data List, Array etc.

If you only need the functionality exposed and implemented in IEnumerable<T>, you should go with that. An alternative is IEnumerable<T> where T : IFoo if you want to be able to iterate over objects that implements the interface IFoo. If you, however, require properties like Count and such that List<T> exposes, you should go for that. Find the lowest common denominator and go with that as it makes your methods more versatile and easier to work with.

IEnumerable has a clean read-only and enumerable or queriable semantics. With List it looks like you allow anybody modify it:).

One advantage to IEnumerable that hasn t yet been mentioned: Contravariance. A routine expecting an IEnumerable(Of Car) will be perfectly happy if given an IEnumerable(Of HondaCivic), which in turns means it would be happy with an IList(Of HondaCivic). By contrast, a routine which expects an IList(Of Car) will not be satisfied with an IList(of HondaCivic). If Microsoft IList were derived from a read-only IReadableByIndex interface, then code which expected an IReadableByIndex(Of Car) would be perfectly happy with IReadableByIndex(Of HondaCivic), but that s water under the bridge.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签