Difference between ICollection, IList and List?


What is the difference between ICollection , IList and List ?

When should I use each one specifically?

asked by anonymous 23.07.2015 / 17:48

1 answer


The first two are interfaces. The latter is a concrete implementation. There is a hierarchy there. The type List implements an IList " which in turn implements an ICollection . It's also worth mentioning IEnumerable that is implemented by ICollection .

  • IEnumerable allows you to enumerate items.

    public interface IEnumerable<out T> : IEnumerable {
        new IEnumerator<T> GetEnumerator();
  • The ICollection allows you to count how many items exist in the enumeration, add, remove items at the end of the collection, check for existence, among other operations.

    public interface ICollection<T> : IEnumerable<T> {
        int Count { get; }
        bool IsReadOnly { get; }
        void Add(T item);
        void Clear();
        bool Contains(T item); 
        void CopyTo(T[] array, int arrayIndex);
        bool Remove(T item);
  • IList also allows you to insert and remove items in any position and search for items by index.

    public interface IList<T> : ICollection<T> {
        T this[int index] { get; set; }
        int IndexOf(T item);
        void Insert(int index, T item);
        void RemoveAt(int index);

At least they indicate that there are methods that allow doing these operations. Of course the correct implementation of these methods in the concrete class will ensure that everything works as expected.

Obviously the interfaces do not allow you to perform any operation with them purely, you need the concrete type which in this case is List .

Interfaces are used to generalize the type of a variable, parameter, or method return. And this is important for harnessing code and making maintenance easier. Whenever possible, you should opt for the most general type possible through the interface.

List<string> listaC = new List<string>();
IList<string> lista = new List<string>();
ICollection<string> colecao = new List<string>();
IEnumerable<string> enumeracao = new List<string>();

Note that all variables implement the List class. But variables that use interface may have their content replaced by objects of other concrete types or not without any problem, as long as these types also implement the interface that the variable was declared. For example, the variable colecao could swap its content with a LinkedList which also implements a ICollection<T> with no problems. Both types have everything the variable type has declared. Example:

colecao = new LikedList();

An important thing that, besides generalizing the use when using the interface, is that it also protects from misuse. In the example, the enumeracao variable even though it implements a list and has everything a list allows, the compiler prevents access to members that are not of type IEnumerable<T> . That is, you can not call the Add() method, or the index operator [] or even Find() . In particular it is there, but as the code said that the variable is of a higher type, the compiler only lets you access what is in this type, so you can only access GetEnumerator() .

enumeracao.Reverse(); //gera erro de compilação
colecao[0]; //erro também.
lista.RemoveAt(0); //funciona
listaC.Add("teste"); //funciona, o método está dentro da hierarquia

Obviously if you need to access a Insert() , you can not only work with a type IEnumerable or even ICollection . But you can use IList instead of using the actual list itself. Since the use of Sort() would require the use of the concrete type List .

Note that this generalization by the interface is more advantageous when used with parameters and methods return.

The subject is broad but the fundamental idea is this.

Remember that generic types are better than these simple types that are considered obsolete, ie it is best to use: ICollection<Tipo> , IList<Tipo> and List<Tipo> .

Source code for List<T> .

Remembering that we should program for the interface and not for the implementation .

23.07.2015 / 17:59