在我的代码中,我需要使用 IEnumerable<>
多次,导致 ReSharper 错误“Possible multiple enumeration of 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
然后避免可能的多重枚举,但我没有得到我可以处理的最高对象。 - 我可以做的另一件事是转换
IEnumerable
至List
在方法的开头:
public List<object> Foo(IEnumerable<object> objects)
{
var objectList = objects.ToList();
// ...
}
但这只是尴尬。
在这种情况下你会怎么做?
最佳答案
将 IEnumerable
作为参数的问题是它告诉调用者“我希望枚举这个”。它不会告诉他们您想枚举多少次。
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.
取至高无上的目标是崇高的,但它给太多的假设留下了空间。您真的希望有人将 LINQ to SQL 查询传递给此方法,只让您枚举它两次(每次都可能获得不同的结果吗?)
这里缺少的语义是调用者可能不会花时间阅读方法的详细信息,可能会假设您只迭代一次 - 因此他们会向您传递一个昂贵的对象。您的方法签名不表示任何一种方式。
通过将方法签名更改为 IList
/ICollection
,您至少可以让调用者更清楚您的期望是什么,并且他们可以避免代价高昂的错误。
否则,大多数查看该方法的开发人员可能会假设您只迭代一次。如果采用 IEnumerable
非常重要,您应该考虑在方法的开头执行 .ToList()
。
遗憾的是 .NET 没有 IEnumerable + Count + Indexer 接口(interface),没有添加/删除等方法,我怀疑这可以解决这个问题。
关于c# - 处理可能的 IEnumerable 多重枚举警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8240844/