IEnumerable<T>
is an interface that is implemented by List<T>
. I suspect the reason you're hearing that IEnumerable<T>
should be used is because it's a less constrictive interface requirement.
For example, consider the following method signature:
void Output(List<Foo> foos)
{
foreach(var foo in foos) { /* do something */ }
}
This method requires that it be passed a concrete implementation of a List. But it's just doing something in-order. It doesn't really need random access or any of the other things that a List<T>
or even an IList<T>
give it. Instead, the method should accept an IEnumerable<T>
:
void Output(IEnumerable<Foo> foos)
{
foreach(var foo in foos) { /* do something */ }
}
Now we're using the most general (least specific) interface that supports the operations that we need. This is a fundamental aspect of OO-design. We've decreased coupling by requiring only what we need, and not a whole lot else besides. We've also created a more flexible method because the foos
parameter might be a Queue<T>
, a List<T>
, anything that implements IEnumerable<T>
. We aren't forcing the caller to convert their data structure to a List unnecessarily.
So it isn't that IEnumerable<T>
is more efficient than list in a "performance" or "runtime" aspect. It's that IEnumerable<T>
is a more efficient design construct because it's a more specific indication of what your design requires. (Though this can lead to runtime gains in specific cases.)