I have been playing around with C# for Windows and ASP.net MVC development for some time now. But I am still unclear on a few areas. I am trying to understand the basic difference between and performance issues with using and interchanging similar kinds of Generic Collection Interfaces.

What is the basic difference between IEnumerable<T>, ICollection<T>, List<T>(Class)?

I seem to use and interchange them without seeing any problem in my applications. Also, are there any more similar generic collections like these that can be interchanged with those three?

  • 2
    there is also IList<T> as well
    – jk.
    Commented Nov 8, 2011 at 13:50

3 Answers 3


List<T> is a class and implements both the ICollection<T> and IEnumerable<T> interfaces. Also, ICollection<T> extends the IEnumerable<T> interface. They are not interchangeable, at least not from all points of view.

If you have a List<T>, you are guaranteed that this object implements methods and properties required to be implemented by the ICollection<T> and IEnumerable<T> interface. The compiler knows it and you are allowed to cast them "down" to either an ICollection<T> or an IEnumerable<T> implicitly. However, if you have an ICollection<T> you have to check explicitly in your code first whether it is a List<T> or something else, perhaps a Dictionary<T> (where T is a KeyValuePair) before casting it to what you desire.

You know that ICollection extends IEnumerable, so you can cast it down to an IEnumerable. But if you only have an IEnumerable, again you are not guaranteed that it is a List. It may be, but it could be something else. You should expect an invalid cast exception if you do attempt to cast a List<T> to a Dictionary<T> for example.

So they are not "interchangeable".

Also, there are a lot of generic interfaces, check out what you can find in the System.Collections.Generic namespace.

Edit: regarding your comment, there is absolutely no performance penalty if you use List<T> or one of the interfaces it implements. You will still need to create a new object, check out the following code:

List<T> list = new List<T>();
ICollection<T> myColl = list;
IEnumerable<T> myEnum = list;

list, myColl, and myEnum all point to the same object. Whether you declare it as a List or an ICollection or an IEnumerable I'm still requiring the program to create a List. I could have wrote this:

ICollection<T> myColl = new List<T>();

myColl, at runtime is still a List.

However, an this is the most important point... to reduce coupling and increase maintainability you should always declare your variables and method parameters using the lowest possible denominator possible for you, whether it is an interface or an abstract or concrete class.

Imagine that the only thing the "PerformOperation" method needs is to enumerate elements, do some work and exit, in that case you do not need the hundred more methods available in List<T>, you only need what is available in IEnumerable<T>, so the following should apply:

public void PerformOperation(IEnumerable<T> myEnumeration) { ... }

By doing that, you and other developers know that any object of a class implementing the IEnumerable<T> interface may be given to this method. It may be a List, a Dictionary, or a custom collection class another developer has wrote.

If on the contrary you specify you explicitly need a concrete List<T> (and although it is rarely the case in real life, it may still happen), you and other developers know that it must either be a List or another concrete class inheriting from List.

  • First of all thanks. Now, the point of concern is how to decide which to use ??. Since List<T> implements both the interfaces, why not always use it in every place where IEnumerable or ICollection is required. Will always using list have a performance impact ? Please edit your answer to reply for these concerns Commented Nov 8, 2011 at 7:48
  • I edited to answer your performance questions
    – Jalayn
    Commented Nov 8, 2011 at 8:11
  • +1, but I would add that in the rare cases where you actually need the to pass a list to a method, you should use IList rather than List in the method declaration.
    – Konamiman
    Commented Jul 25, 2013 at 9:03
  • @Konamiman - Depends if you need List<> specific functionality, like .AddRange(). The IList<> doesn't expose that.
    – Bobson
    Commented Jul 25, 2013 at 15:13

Have a look at the MSDN pages for ICollection and IEnumerable.

In very abstract terms, this is how I conceive of these types.

An IEnumerable is anything that can be enumerated - that is, iterated over. It doesn't necessarily mean a 'collection'; for example, an IQueryable implements IEnumerable and it's not a collection, but is something that can be queried to return objects. To implement IEnumerable an object only needs to be able to return an object when queried. I might say that I have an Enumerable of tasks that I'm going to do today (it's not a list because I haven't written it down or formulated it, but I could tell you what I'm going to do now, and if you asked 'and then?' I'd be able to tell you the following task).

An ICollection is more concrete than an IEnumerable. A key difference is that a Collection knows how many items it contains; to work out how many items are in an Enumerable you effectively loop through and count them:

Me: Guys, how many items do you each have in you?

Enumerable: I don't really know. Well, here's one item. I've got another one, so that's two. And another one, so that's three... and another one... ok so that's 2382. No more items, so I've got 2382. Don't ask me again because I'll have to go through them all again.

Collection: I've got 2382 items. I already know that.

A collection is typically something that already knows where all its elements are, and won't have to go and find or generate them when you ask for them. It's more... concrete than an Enumerable.

In my opinion the different between an Enumerable and a Collection is much larger than the difference between a Collection and a List. In fact I'm struggling to think of a practical difference between a Collection and a List, but I believe List provides better methods for searching and ordering.

Other types of Collection include Queue and Stack, as well as Dictionary.

The names of these types are quite useful - you can conceive of a queue and a stack as their real world counterparts, and consider the differences you might have to a List.

  • "I'm struggling to think of a practical difference between a Collection and a List" ... Later in your answer you answer this yourself. A List is an ICollection, but an ICollection isn't always a List (Queue, Stack, Dictionary, ...) Commented Nov 8, 2011 at 10:14
  • @Steven It's a very rambling answer. I agree that this is an important difference, but I wouldn't call it a practical difference. What does it mean to the user? Commented Nov 8, 2011 at 12:51
  • That's easy! :) Queue<int> queue = (Queue<int>)list; will throw an InvalidCastException when list is not a Queue<int>. The difference between queue and list is out of scope for this question. Commented Nov 8, 2011 at 12:54
  • Isn't the critical aspect of IEnumerable that it can return the current and next items - you sort of allude to that, but don't explicitly say so. Essentially something that implements IEnumerable alone can't return an arbitrary item of its members when queried - only the current one and the next one.
    – cori
    Commented Nov 15, 2011 at 0:00
  • @cori That's a very succinct way of putting it, a lot clearer than my answer. Commented Nov 15, 2011 at 1:22


query isn't executed until to really iterate over the items, maybe by doing a .ToList()


forward-only list of items. You can't get at "item 4" without passing items 0-3. read-only list, you can't add to it or remove from it. Still might use deferred execution.


random access to the full list entirely in memory supports adding and removing


Is between IEnumerable and IList. What is "best" depends on your requirements. Usually though an IEnumerable is "good enough" if you only want to display items. At least always use the generic variant.

  • this answer does not appear to add anything valuable over what has been already posted in earlier answers
    – gnat
    Commented Jul 25, 2013 at 6:27
  • it's just a simple concept about all
    – Zia Qammar
    Commented Jul 25, 2013 at 6:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.