Difference between Icollection, Ilist and List?

Asked

Viewed 13,752 times

49

What’s the difference between ICollection, IList and List?

When I should use each one specifically?

1 answer

70


The first two are interfaces. The last one is a concrete implementation. There is a hierarchy. The type List implements a IList which in turn implements a ICollection. It is interesting to quote IEnumerable which is implemented by ICollection.

  • To IEnumerable allows you to list items.

      public interface IEnumerable<out T> : IEnumerable {
          new IEnumerator<T> GetEnumerator();
      }
    
  • To ICollection allows you to count how many items there are in the enumeration, add, remove items at the end of the collection, check for existence, and 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);
      }
    
  • To IList allows you to insert and remove items at 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 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 to carry out any operation with them purely, you need the concrete type that in the case is the List.

Interfaces are used to generalize the type of a variable, parameter or return of a method. And this is important to take advantage of code and facilitate maintenance. Wherever possible one should opt for the most general type possible, 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 class List. But variables that use interface can have their content replaced by objects of other concrete types or not without any problem, since these types also implement the interface that the variable was declared. For example, the variable colecao could exchange its contents for a LinkedList which also implements a ICollection<T> no problem. Both types have everything the type of the variable was declared. Example:

colecao = new LikedList();

One important thing that besides generalizing the use when using the interface, is that it also protects from misuse. In the example the variable enumeracao despite implementing a list and having everything a list allows, the compiler prevents access to members who are not part of the type IEnumerable<T>. I mean, you can’t call the method Add(), or the index operator [] or the Find(). Concretely 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 the 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

I put in the Github for future reference.

Obviously if you need to access one Insert(), you can’t work with just one guy IEnumerable or even ICollection. But you can use a IList instead of using the same concrete list. Already the use of the 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 return of methods.

The subject is broad but the fundamental idea is this.

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

Source code of List<T>.

Remembering that we must program to the interface and not to the implementation.

  • 1

    Now it’s clear. Thank you very much. Have a nice lunch.

  • 1

    Very good your answer, yielded up a post on my blog.

  • 1

    +1 good answer.

  • 1

    That fellow, a real lesson! Decision making already made after reading this. Congratulations.

  • @Pacheco thank you, I hope it was a good decision whatever it is :)

  • 1

    I always use the List when I need a List of objects of a certain type. At most an ADD or Count etc is more basic than I use. But from now on I will always use Icollection<Person> People { get; set; } because I have more options.

  • Simple and objective! Very good guy!

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.