If we want to get from the method List<T> how to do it correctly:

  1. List<T> Method() {...}
  2. IList<T> Method() {...}
  3. IEnumerable<T> Method() {...}
  4. ICollection<T> Method() {...}

and why?

If we want to pass to the List<T> method, how it should be:

  1. void Method(List<T> list) {...}
  2. void Method(IList<T> list) {...}
  3. void Method(IEnumerable<T> list) {...}
  4. void Method(ICollection<T> list) {...}

and why?

PS In principle, both situations are of interest for both public and private . Here the Entity Framework generates methods with an ICollection for example. And many examples when people work through IEnumerable. Why is that?

  • Comments are not intended for extended discussion; conversation moved to chat . - Nick Volynkin

2 answers 2

Let's see. First, the result returned from the method.

Firstly - for rigorous interfaces (and a sheet) are built from IEnumerable -> ICollection -> IList -> List (the actual implementation of IList ).

IEnumerable is an enumeration that may not have an end to which elements cannot be added.

ICollection -> IList - collections that have a fixed number of elements, you can add and remove elements, small differences between them are usually not significant.

List is a concrete implementation of the IList interface.

No interface can guarantee that the List returned. Therefore, if you need to return a List from a method, then it is with this type that the method should be.


But with the transfer of the sheet is much more complicated. The subject area is very important here.

If it is conditional the method of adding elements to the sheet - then only the sheet method should accept.

If the method sorts a sheet without using anything specific, it is quite possible to extend the effect on the IList .

If the method does not touch the incoming sheet, but generates a new list of it - then you can actually submit even an IEnumerable to the input, however, in order not to get something suspicious you can reduce it to an ICollection .

In fact, by the same rigor you sort the interfaces and see which method can still work with.


In addition to all the above, everything except IEnumerable can be changed by both parties, both the method and the one who called it. This should be taken into account with both incoming and return values.

  • Thank you, informative. With your permission, I will wait, who knows, who is still ripe for a good answer. - Bulson
  • @Bulson actually, you have a common question to answer it well. Try to formulate a question more specifically to understand what the problem is. - Monk
  • I'm just concerned in general :) How to do it right? Very often I met and I meet that people return from the IEnumerable method, and I myself always returned what I expected (wanted) - the List , and the question has matured. - Bulson
  • @Bulson while you are satisfied with the sheet - and use it. So in most cases, these troubles are needed only in very large projects with a bunch of layers and all garbage such as mocks \ tests \ etc. - Monk
  • well thank you. - Bulson

If we want to get from the List<T> method, then we need to return a List<T> . It's just that simple.

The question is usually different: what should we want to get from the method? Is it important for us that the method returns a List<T> , or would we be satisfied with the ObservableCollection<T> in the same way or if we allow T[] ? If we are indifferent to what specific type the method returns, and only the list is needed, it makes sense to pawn the requirements more weakly: set the return value to IEnumerable<T> . Or ICollection<T> , if we need to be able and add. Or IReadOnlyCollection<T> , if we need only a fixed list for reading. Etc.

A similar consideration works for argument collections.

The general principle - specify the weakest type of those that suit you. This will give you the freedom to change the implementation of the method without breaking the code on the client side.

There is no common recipe once and for all, because each method has its own requirements. Specify the type depending on the requirements, and not according to formal criteria.

  • Good advice, thanks. - Bulson
  • @Bulson: Please! - VladD