If I have a function that takes a collection of a certain type, what parameter type should I use?
I have previously assumed IEnumerable
is the default, but I would like to know if this is correct and if so, why.
ICollection
also seems like a valid candidate (due to its name), but I get the impression IEnumerables are more user friendly.
I figured looking at examples the framework gives us would be a good idea, but I find that something like String.Join
, asks for an array of strings.

- 6,926
- 5
- 62
- 86
-
1This have been answered before here: http://stackoverflow.com/questions/3559868/list-ilist-ienumerable-iqueryable-icollection-which-is-most-flexible-return Best regards. – Oscar Jun 11 '12 at 10:21
-
3[`String.Join`](http://msdn.microsoft.com/en-us/library/dd992421.aspx) had an overload added in the .NET 4 timeframe so that it takes an `IEnumerable`. The overload taking the array dates from the pre-generic days... – Damien_The_Unbeliever Jun 11 '12 at 10:21
-
7@Oscar: that's about the return type—I'm talking parameters. – Protector one Jun 11 '12 at 10:23
-
What collection types you want to support for the parameter: Stack? Queue? Dictionary? Array? or some other and do you want read-only access or read-write access to your collections inside your parameterized function? These would help to better explain in the answer and more suggestions.. – S2S2 Jun 11 '12 at 11:09
-
@CSharpVJ: That depends on the situation. I'm asking for the general case, not a specific one. – Protector one Jun 11 '12 at 11:33
-
1@Protectorone thats all right. I updated my answer to show both generalized and specific suggestions. Specially, the links to blog posts in my answer would be helpful to you in a better way.. – S2S2 Jun 11 '12 at 11:36
3 Answers
You take the one that imposes the least on clients but allows you to get your job done. If you can get away with IEnumerable<T>
over ICollection<T>
, then you should use it because this gives greater flexibility to clients of your API.

- 175,602
- 35
- 392
- 393
-
Agreed. However, be aware of [possible multiple enumerations of IEnumerable](https://www.jetbrains.com/help/resharper/PossibleMultipleEnumeration.html) when handling IEnumerable objects passed as input parameters in a method. If you can guarantee the method consumers will always provide either Lists, Arrays or Collections, you can then use ICollection
instead. Otherwise, you would need to enumerate your entire enumeration (e.g. converting ToList()) once, and then work with the enumerated object. – Lesair Valmont Sep 09 '19 at 14:24
IEnumerable are more preferred over ICollections. Here is the generous answer to your question.

- 1
- 1

- 14,315
- 2
- 32
- 54
Interfaces are mostly used as parameters or return types in functions to support the I
in SOLID
Design Principles (Interface Segregation Principle) for making casting easier, to support passing multiple concrete types to the interfaced parameters and hiding (encapsulating) the actual parameter type from the clients of your public functions.
- About
IEnumerable
:
Very basic, It Exposes the enumerator, which supports a simple iteration over a non-generic collection.
[ComVisibleAttribute(true)]
public interface IEnumerable
- Here's about
ICollection
:
The ICollection interface extends IEnumerable; IDictionary and IList are more specialized interfaces that extend ICollection. An IDictionary implementation is a collection of key/value pairs, like the Hashtable class. An IList implementation is a collection of values and its members can be accessed by index, like the ArrayList class. Some collections that limit access to their elements, such as the Queue class and the Stack class, directly implement the ICollection interface. If neither the IDictionary interface nor the IList interface meet the requirements of the required collection, derive the new collection class from the ICollection interface instead for more flexibility.
[ComVisibleAttribute(true)]
public interface ICollection : IEnumerable
Here's about
IList
interface:[ComVisibleAttribute(true)] public interface IList : ICollection, IEnumerable
More from MSDN about IList:
IList
is a descendant of the ICollection
interface and is the base interface of all non-generic lists. IList implementations fall into three categories: read-only, fixed-size, and variable-size. A read-only IList cannot be modified. A fixed-size IList does not allow the addition or removal of elements, but it allows the modification of existing elements. A variable-size IList allows the addition, removal, and modification of elements.
Tip:
In case you just want to support
foreach
for your collection parameter,IEnumerable
should be enough. In case you also want the support for adding and removing items from the collection,IList
is the better choice.
Suggestions: This blog post: IEnumerable, ICollection, IList Compared should certainly help you to take better and precise decision.
Additionally, look at this article for performance and other comparisons of IList and IEnumerable.

- 8,322
- 5
- 37
- 65
-
3-1: I couldn't disagree more. **Always** (for a given value of always) use the minimum abstraction that gets the job done, that way your client code (the code you're writing) isn't constrained to using the same container, you're function becomes more generic and has greater potential for re-use. – Binary Worrier Jun 11 '12 at 10:37
-
Well @BinaryWorrier I updated the answer to use IList to be a choice only when the support to add or remove items is required and to use IEnumerable if only foreach support is required..I hope you understood the answer better now.. – S2S2 Jun 11 '12 at 10:49
-
1Sorry but I still disagree. `IEnumerable
` should be preferred as it is the minimum abstraction. e.g. Lets imagine you have a function that takes a list of numbers and gets the min, max and average. If the function takes an ICollection it can be used by any class that implements I collection. If it's written to take IEnumerable, it can work on _anything_, as you easily write an adapter for DataReaders or file readers that `yield return` items without causing additional storage or processing overhead, and still use the same function. – Binary Worrier Jun 11 '12 at 10:57 -
@BinaryWorrier Though you disagree with my answer, I completely agree with your comments. Provided the original `question` gave a hint clearly about read-only usage or read-write usage (of required collection parameter), the answers would have been more concrete and to the point... – S2S2 Jun 11 '12 at 11:00