What is the difference between returning IList vs List, or IEnumerable vs List.
I want to know which is better to return.
When we need to use one, what effect will it have on performance?
Like IEnumerable, IList is also best to query data from in-memory collections like List, Array etc. IList is useful when you want to Add or remove items from the list. IList can find out the no of elements in the collection without iterating the collection. IList supports deferred execution.
You want to aim for the least possible coupling, so return an IEnumerable<T> if that is enough. It probably will be. Return an IList<T> if the situation requires that the caller gets a List that it can use to Add/Insert/Remove.
The main difference between List and IList in C# is that List is a class that represents a list of objects which can be accessed by index while IList is an interface that represents a collection of objects which can be accessed by index.
IEnumerable is conceptually faster than List because of the deferred execution. Deferred execution makes IEnumerable faster because it only gets the data when needed. Contrary to Lists having the data in-memory all the time.
There is no such a type that is always better to return. It's a decision you should make based on your design/performance/etc goals.
IEnumerable<T>
is nice to use when you want to represent sequence of items, that you can iterate over, but you don't want to allow modifications(Add, Delete etc).
IList<T>
gives you everything you could get using IEnumerable<T>
, plus operations that give you more control over a collection: Add, Delete, Count, Index access etc.
List<T>
is a concrete implementation of IList<T>
. I would say that almost always it's better to expose IList<T>
interface from your methods rather that List<T>
implementation. And it's not just about lists - it's a basic design principle to prefer interfaces over concrete implementations.
Ok, now about non-generic versions IEnumerable, IList, List
:
They actually came from very early versions of .NET framework, and life is much better using generic equivalents.
And few words about performance:
IEnumerable<T>
(with IEnumerator<T>
) is actually an iterator which allows you to defer some computations until later. It means that there is no need to allocate memory right away for storing amounts of data(of course, it's not the case when you have, say, array behind iterator). You can compute data gradually as needed. But it means that these computations might be performed over and over again(say, with every foreach
loop). On the other hand, with List you have fixed data in memory, with cheap Index and Count operations. As you see, it's all about compromise.
Using concrete classes in parameters and results of methods makes a strong dependency, while using interfaces don't. What it mean?
If in the future you'll change the implementation of your class, and will use SynchroinizedCollection
, LinkedList
, or something other instead of List
, then you have to change your methods signature, exactly the type of return value.
After that you have to not only rebuild assemblies that used this class, but may have to rewrite them.
However, if you're using one of IEnumerable
, IReadonlyCollection
, ICollection
, IList
interfaces, you'll not have to rewrite and recompile client assemblies. Thus, interfaces always preferred classes in parameters and results. (But remember, we're talking about dependencies between different assemblies. With the same assembly this rule is not so important.)
The question is, what interface to use? It depends on requirements of client classes (use cases). F.e. if you're processing elements one by one, use IEnumerable<T>
, and if you need a count of elements, use IReadonlyCollection<T>
. Both of these interfaces are co-variance that is convenient for a type-casting.
If you need write abilities (Add
, Remove
, Clear
) or non co-variance read only abilities (Contains
), use ICollection<T>
. Finally, if you need a random indexed access, use IList<T>
.
As for performance, the invocation of interface's method a bit slower, but it's insignificant difference. You shouldn't care about this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With