Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the role of IEnumerable<T> and why should I use it?

Why should I use IEnumerable<T> when I can make do with...say List<T>? What's the advantage of the former over the latter?

like image 671
Deepanjan Nag Avatar asked Jun 06 '11 19:06

Deepanjan Nag


3 Answers

IEnumerable<T> is an interface that tells us that we can enumerate over a sequence of T instances. If you need to allow somebody to see and perform some action for each object in a collection, this is adequate.

List<T>, on the other hand, is a specific implementation of IEnumerable<T> that stores the objects in a specific, known manner. Internally, this may be a very good way to store your values that you expose via IEnumerable<T>, but a List<T> is not always appropriate. For example, if you do not need to access items by index, but constantly insert items at the beginning of your collection and then remove items from the end, a Queue<T> would be far more appropriate to use.

By using IEnumerable<T> in your API, you provide yourself the flexibility to change the internal implementation at any time without changing any other code. This has huge benefits in terms of allowing your code to be flexible and maintainable.

like image 76
Reed Copsey Avatar answered Nov 18 '22 11:11

Reed Copsey


On this point Jeffrey-Richter writes:

When declaring a method’s parameter types, you should specify the weakest type possible, preferring interfaces over base classes. For example, if you are writing a method that manipulates a collection of items, it would be best to declare the method’s parameter by using an interface such as IEnumerable<T> rather than using a strong data type such as List<T> or even a stronger interface type such as ICollection<T> or IList<T>:

// Desired: This method uses a weak parameter type   
public void ManipulateItems<T>(IEnumerable<T> collection) { ... }  

// Undesired: This method uses a strong parameter type   
public void ManipulateItems<T>(List<T> collection) { ... }

The reason, of course, is that someone can call the first method passing in an array object, a List<T> object, a String object, and so on — any object whose type implements IEnumerable<T>. The second method allows only List<T> objects to be passed in; it will not accept an array or a String object. Obviously, the first method is better because it is much more flexible and can be used in a much wider range of scenarios.

Naturally, if you are writing a method that requires a list (not just any enumerable object), then you should declare the parameter type as an IList<T>. You should still avoid declaring the parameter type as List<T>. Using IList<T> allows the caller to pass arrays and any other objects whose type implements IList<T>.

On the flip side, it is usually best to declare a method’s return type by using the strongest type possible (trying not to commit yourself to a specific type).

like image 26
algreat Avatar answered Nov 18 '22 09:11

algreat


Different implementations of collections can be enumerable; using IEnumerable makes it clear that what you're interested in is the enumerability, and not the structure of the underlying implementation of the collection.

As mentioned by Mr. Copsey, this has the benefit of providing decoupling from the implementation, but I'm of the contention that a clear definition of the smallest subset of interface functionality as possible (i.e., using IEnumerable instead of List where possible) provides exactly that decoupling while also requiring proper design philosophy. That is to say, you can achieve decoupling but not achieve minimal dependency, but you cannot achieve minimal dependency without achieving maximal decoupling.

like image 2
Paul Sonier Avatar answered Nov 18 '22 10:11

Paul Sonier