在我的代码中需要IEnumerable<>多次使用,从而得到“可能的多重枚举IEnumerable” 的Resharper错误。
IEnumerable<>
IEnumerable
样例代码:
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; }
objects
List
public List<object> Foo(IEnumerable<object> objects) { var objectList = objects.ToList(); // ... }
但是,这很 尴尬 。
在这种情况下您会做什么?
IEnumerable使用参数作为问题是它告诉调用者“我希望枚举”。它不会告诉他们您希望枚举多少次。
我可以将objects参数更改为List,然后避免可能的多重枚举,但是我没有得到 我能处理的最高对象 。
追求最高目标的目标是崇高的,但它为太多的假设留有余地。您是否真的要有人将LINQ to SQL查询传递给此方法,而只让您枚举两次(每次都可能得到不同的结果?)。
这里缺少的语义是,调用者可能不花时间来阅读方法的详细信息,因此可能会假设您仅迭代一次-因此,它们将为您传递一个昂贵的对象。您的方法签名不指示任何一种方式。
通过将方法签名更改为IList/ ICollection,至少可以使调用者更清楚自己的期望,并且它们可以避免代价高昂的错误。
IList
ICollection
否则,大多数使用该方法的开发人员可能会假设您仅迭代一次。如果采用IEnumerable是如此重要,则应.ToList()在方法开始时考虑进行。
.ToList()
真可惜.NET没有IEnumerable + Count + Indexer接口,没有Add / Remove等方法,这是我怀疑可以解决此问题的方法。