Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling warning for possible multiple enumeration of IEnumerable

In my code I need to use an IEnumerable<> several times, resulting in the ReSharper error of "Possible multiple enumeration of IEnumerable".

Sample code:

public List<object> Foo(IEnumerable<object> objects) {     if (objects == null || !objects.Any())         throw new ArgumentException();              var firstObject = objects.First();     var list = DoSomeThing(firstObject);             var secondList = DoSomeThingElse(objects);     list.AddRange(secondList);          return list; } 
  • I can change the objects parameter to be List and then avoid the possible multiple enumeration but then I don't get the highest object that I can handle.
  • Another thing that I can do is to convert the IEnumerable to List at the beginning of the method:

 public List<object> Foo(IEnumerable<object> objects)  {     var objectList = objects.ToList();     // ...  } 

But this is just awkward.

What would you do in this scenario?

like image 727
gdoron is supporting Monica Avatar asked Nov 23 '11 10:11

gdoron is supporting Monica


People also ask

How do you fix multiple enumeration of IEnumerable?

If the underlying type of the IEnumerable collection is an iterator-based implementation generated by LINQ methods like Select or yield in C# or yield statement in Visual Basic, you can fix the violation by converting and caching the collection to another type.

How do you fix multiple enumerations?

This kind of problem can be easily fixed — force the enumeration at the point of variable initialization by converting the sequence to an array or a list, for example: List<string> names = GetNames().

What does possible multiple enumeration mean?

Deferred Danger. One of the many useful warnings in ReSharper is “Possible multiple enumeration of IEnumerable“. If you enumerate an enumerable more than once, ReSharper detects that and warns you about it. Although this warning may seem pointless at first, there are two good reasons to pay attention to it.

What is IEnumerable C#?

IEnumerable in C# is an interface that defines one method, GetEnumerator which returns an IEnumerator interface. This allows readonly access to a collection then a collection that implements IEnumerable can be used with a for-each statement.


Video Answer


1 Answers

The problem with taking IEnumerable as a parameter is that it tells callers "I wish to enumerate this". It doesn't tell them how many times you wish to enumerate.

I can change the objects parameter to be List and then avoid the possible multiple enumeration but then I don't get the highest object that I can handle.

The goal of taking the highest object is noble, but it leaves room for too many assumptions. Do you really want someone to pass a LINQ to SQL query to this method, only for you to enumerate it twice (getting potentially different results each time?)

The semantic missing here is that a caller, who perhaps doesn't take time to read the details of the method, may assume you only iterate once - so they pass you an expensive object. Your method signature doesn't indicate either way.

By changing the method signature to IList/ICollection, you will at least make it clearer to the caller what your expectations are, and they can avoid costly mistakes.

Otherwise, most developers looking at the method might assume you only iterate once. If taking an IEnumerable is so important, you should consider doing the .ToList() at the start of the method.

It's a shame .NET doesn't have an interface that is IEnumerable + Count + Indexer, without Add/Remove etc. methods, which is what I suspect would solve this problem.

like image 126
Paul Stovell Avatar answered Sep 24 '22 19:09

Paul Stovell