c# - IEnumerable vs List - What to Use? How do they work?

ID : 2210

viewed : 104

Tags : c#linqlistienumerablec#

Top 5 Answer for c# - IEnumerable vs List - What to Use? How do they work?

vote vote

93

IEnumerable describes behavior, while List is an implementation of that behavior. When you use IEnumerable, you give the compiler a chance to defer work until later, possibly optimizing along the way. If you use ToList() you force the compiler to reify the results right away.

Whenever I'm "stacking" LINQ expressions, I use IEnumerable, because by only specifying the behavior I give LINQ a chance to defer evaluation and possibly optimize the program. Remember how LINQ doesn't generate the SQL to query the database until you enumerate it? Consider this:

public IEnumerable<Animals> AllSpotted() {     return from a in Zoo.Animals            where a.coat.HasSpots == true            select a; }  public IEnumerable<Animals> Feline(IEnumerable<Animals> sample) {     return from a in sample            where a.race.Family == "Felidae"            select a; }  public IEnumerable<Animals> Canine(IEnumerable<Animals> sample) {     return from a in sample            where a.race.Family == "Canidae"            select a; } 

Now you have a method that selects an initial sample ("AllSpotted"), plus some filters. So now you can do this:

var Leopards = Feline(AllSpotted()); var Hyenas = Canine(AllSpotted()); 

So is it faster to use List over IEnumerable? Only if you want to prevent a query from being executed more than once. But is it better overall? Well in the above, Leopards and Hyenas get converted into single SQL queries each, and the database only returns the rows that are relevant. But if we had returned a List from AllSpotted(), then it may run slower because the database could return far more data than is actually needed, and we waste cycles doing the filtering in the client.

In a program, it may be better to defer converting your query to a list until the very end, so if I'm going to enumerate through Leopards and Hyenas more than once, I'd do this:

List<Animals> Leopards = Feline(AllSpotted()).ToList(); List<Animals> Hyenas = Canine(AllSpotted()).ToList(); 
vote vote

88

There is a very good article written by: Claudio Bernasconi's TechBlog here: When to use IEnumerable, ICollection, IList and List

Here some basics points about scenarios and functions:

enter image description here enter image description here

vote vote

74

A class that implement IEnumerable allows you to use the foreach syntax.

Basically it has a method to get the next item in the collection. It doesn't need the whole collection to be in memory and doesn't know how many items are in it, foreach just keeps getting the next item until it runs out.

This can be very useful in certain circumstances, for instance in a massive database table you don't want to copy the entire thing into memory before you start processing the rows.

Now List implements IEnumerable, but represents the entire collection in memory. If you have an IEnumerable and you call .ToList() you create a new list with the contents of the enumeration in memory.

Your linq expression returns an enumeration, and by default the expression executes when you iterate through using the foreach. An IEnumerable linq statement executes when you iterate the foreach, but you can force it to iterate sooner using .ToList().

Here's what I mean:

var things =      from item in BigDatabaseCall()     where ....     select item;  // this will iterate through the entire linq statement: int count = things.Count();  // this will stop after iterating the first one, but will execute the linq again bool hasAnyRecs = things.Any();  // this will execute the linq statement *again* foreach( var thing in things ) ...  // this will copy the results to a list in memory var list = things.ToList()  // this won't iterate through again, the list knows how many items are in it int count2 = list.Count();  // this won't execute the linq statement - we have it copied to the list foreach( var thing in list ) ... 
vote vote

68

Nobody mentioned one crucial difference, ironically answered on a question closed as a duplicated of this.

IEnumerable is read-only and List is not.

See Practical difference between List and IEnumerable

vote vote

55

The most important thing to realize is that, using Linq, the query does not get evaluated immediately. It is only run as part of iterating through the resulting IEnumerable<T> in a foreach - that's what all the weird delegates are doing.

So, the first example evaluates the query immediately by calling ToList and putting the query results in a list.
The second example returns an IEnumerable<T> that contains all the information needed to run the query later on.

In terms of performance, the answer is it depends. If you need the results to be evaluated at once (say, you're mutating the structures you're querying later on, or if you don't want the iteration over the IEnumerable<T> to take a long time) use a list. Else use an IEnumerable<T>. The default should be to use the on-demand evaluation in the second example, as that generally uses less memory, unless there is a specific reason to store the results in a list.

Top 3 video Explaining c# - IEnumerable vs List - What to Use? How do they work?

Related QUESTION?