Can anyone explain to me why I would want to use IList over List in C#?
Related question: Why is it considered bad to expose List<T>
Can anyone explain to me why I would want to use IList over List in C#?
Related question: Why is it considered bad to expose List<T>
If you are exposing your class through a library that others will use, you generally want to expose it via interfaces rather than concrete implementations. This will help if you decide to change the implementation of your class later to use a different concrete class. In that case the user's of your library won't need to update their code since the interface doesn't change.
If you are just using it internally, you may not care so much, and using List<T> may be ok.
IList<T> is an interface so you can inherit another class and still implement IList<T> while inheriting List<T> prevents you to do so.
For example if there is a class A and your class B inherits it then you can't use List<T>
class A : B, IList<T> { ... }
You would because defining an IList or an ICollection would open up for other implementations of your interfaces.
You might wantet to have a IOrderRepository that defines a collection of orders in either a IList or ICollection, then you could have different kinds of implementations provide a list of orders as long as they conform to "rules" defined by your IList or ICollection.
A principle of TDD and OOP generally is programming to an interface not an implementation.
In this specific case since you're essentially talking about a language construct, not a custom one it generally won't matter, but say for example that you found List didn't support something you needed. If you had used IList in the rest of the app you could extend List with your own custom class and still be able to pass that around without refactoring.
The cost to do this is minimal, why not save yourself the headache later? It's what the interface principle is all about.
public void Foo(IList<Bar> list)
{
// Do Something with the list here.
}
In this case you could pass in any class which implements the IList<Bar> interface. If you used List<Bar> instead, only a List<Bar> instance could be passed in.
The IList<Bar> way is more loosely coupled than the List<Bar> way.
The most important case for using interfaces over implementations is in the parameters to your API. If your API takes a List parameter, then anyone who uses it has to use List. If the parameter type is IList, then the caller has much more freedom, and can use classes you never heard about, which may not even have existed when your code was written.
List< T > is a specific implementation of IList< T >, which is a container that can be addressed the same way as a linear array T[] using an integer index. When you specify IList as the type of the method's argument, you only specify that you need certain capabilities of the container.
For example, the interface specification does not enforce a specific data structure to be used. The implementation of List< T > happens to the same performance for accessing, deleting and adding elements as a linear array. However, you could imagine an implementation that is backed by a linked list instead, for which adding elements to the end is cheaper (constant-time) but random-access much more expensive. (Note that the .NET LinkedList< T > does not implement IList< T >.)
This example also tells you that there may be situations when you need to specify the implementation, not the interface, in the argument list: In this example, whenever you require a particular access performance characteristic. This is usually guaranteed for a specific implementation of a container (List< T > documentation: "It implements the IList< T > generic interface using an array whose size is dynamically increased as required.").
Additionally, you might want to consider exposing the least functionality you need. For example. if you don't need to change the content of the list, you should probably consider using IEnumerable< T >, which IList< T> extends.
Interface is a promise (or a contract).
As it is always with the promises - smaller the better.
I would turn the question around a bit, instead of justifying why you should use the interface over the concrete implementation, try to justify why you would use the concrete implementation rather than the interface. If you can't justify it, use the interface.
You can look at this argument from several angles including the one of a purely OO approach which says to program against an Interface not an implementation. With this thought, using IList follows the same principal as passing around and using Interfaces that you define from scratch. I also believe in the scalability and flexibility factors provided by an Interface in general. If a class implmenting IList<T> needs to be extended or changed, the consuming code does not have to change; it knows what the IList Interface contract adheres to. However using a concrete implementation and List<T> on a class that changes, could cause the calling code to need to be changed as well. This is because a class adhering to IList<T> guarantees a certain behavior that is not guaranteed by a concrete type using List<T>.
Also having the power to do something like modify the default implementation of List<T> on a class Implementing IList<T> for say the .Add, .Remove or any other IList method gives the developer a lot of flexibility and power, otherwise predefined by List<T>