views:

470

answers:

7

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.

+4  A: 

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.

Jeff Sternal
+10  A: 

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).

Jon Skeet
Since `IEnumerable<T>` is immutable, you can use this interface when giving back data from your class knowing that no elements will be added or removed. Though the user can still call mutating functions on the objects contained _within_ the enumerable.
Marcel Gosselin
@Marcel: note quite true. The `IEnumerable<T>` interface contains no methods for altering the sequence. The concreted implementation may or may not be mutable. If a method signature says that it returns `IEnumerable<Whatever>` and the code returns a `List<Whatever>`, the calling code can easily cast the returned object to `List<Whatever>` and alter the contents of the list. The signature does however *communicate that the result should be treated as read-only*.
Fredrik Mörk
It's still possible to cast back to `IList<T>` at the call site, so this isn't bullet proof.
recursive
A developer who casts back to IList<T> should have their license revoked!
Phil
A: 

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.

Kevin
+2  A: 

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.

JaredPar
A: 

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.

asbjornu
A: 

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

rudnev
+1  A: 

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.

Derek Greer
Excellent response. You're a little late in the game, but I totally agree. I've learned a whole lot since last Nov. :)
Byron Sommardahl
I thought I'd weigh in for posterity sake :)
Derek Greer