Is there any benefit or difference if my for-each
loop is going through the method argument if I pass in that argument as an IEnumerable
or if I pass that argument as a List
?

- 26,091
- 61
- 167
- 254
-
The difference between passing things around as an `IEnumerable` (and, by that, I'm assuming `IEnumerable
`) and `List – Flydog57 Feb 12 '19 at 18:48` is method that has an `IEnumerable ` parameter (or a caller who gets an `IEnumerable ` as a return type) gets a collection that cannot be changed. `List ` parameters (and return types) allow the receivers of the list to change the contents of the list. -
@Flydog57, well a collection can still be changed, even when passed as an `IEnumerable
` reference, simply by for example doing something like `(enumerable as ICollection – Feb 12 '19 at 19:35)?.Clear();`. I believe you meant to say a method with an IEnumerable parameter is indicating that it will not modify any collection passed as argument...
5 Answers
If your IEnumerable is implemented by List then no; no difference. There is a big conceptual difference though; the IEnumerable says "I can be enumerated" which means also that the number of items is not known and the enumeration cannot be reversed, or random accessed. The List says "I am a fully formed list, already populated; I can be reversed and randomly accessed".
So you should generally build your function interface to accept the lowest functionality compatible with your operation; if you are only going to enumerate forwards, iteratively, then accept IEnumerable - this allows your function to be used in more scenarios.
If you made your function accept only List() then any caller with an array or IEnumerable passed into it, must convert their input into List() before calling your function - which may well be poorer performance than simply passing through their array or IEnumerable directly. In this sense accepting an IEnumerable invites better performance code.

- 6,182
- 1
- 15
- 25
In the general case, there can be a difference if the collection has an explicit interface implementation of IEnumerable
List has the explicit implementation, but does not change behavior. There is no difference in your case.
See: https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs looking at GetEnumerator
and similar

- 60,462
- 10
- 96
- 117
No there isn't. In both cases the for-each is translated to something like this
var enumerator = input.GetEnumerator();
while(enumerator.MoveNext())
{
// loop body.
// The current value is accessed through: enumerator.Current
}
Additionally, if the enumerator is disposable, it will be disposed after the loop.
Jon Skeet gives a detailed description here.

- 104,806
- 13
- 138
- 188
-
-
Yes, but only if the enumerator is disposable. (Note that I mentioned it but did not include it in the code sample,) – Olivier Jacot-Descombes Feb 12 '19 at 20:15
If you pass the same object, it doesn't matter whether your method accepts IEnumerable or List.
However, if all you're going to do inside the method is enumerate the object, it's best to expect an IEnumerable in the method argument, you don't want to limit the caller of the method by expecting a List.

- 4,800
- 9
- 29
- 57
No, there is no benefit or difference as to how the foreach
loop would go through the collection.
As Olivier Jacot-Descombes has pointed out, the foreach
loop will simply go through the elements one by one using the enumerator.
However, it can make a difference if your logic goes through the same collection at least twice. In this case if IEnumerable<>
is used, you might end up regenerating the elements each time you go over the iterator.
ReSharper even has a special warning for this type of code: PossibleMultipleEnumeration
I am not saying that you should not use IEnumerable<>
. Everything has its time and place and it's not always a good idea to use the most generic interface. Be careful with your choice.

- 802
- 8
- 17