我最初将我的参数类型设置为ICollection,因为我认为我会遇到IEnumerable的多个枚举问题。但是,Resharper建议我可以将参数类型转换为IEnumerable。我最终做了一个双重检查测试,似乎工作正常:
private static void Main(string[] args)
{
var nums = GetNums();
MultipleEnumerations(nums);
Console.ReadLine();
}
private static void MultipleEnumerations(IEnumerable<int> nums)
{
var otherNums = new List<int> {1, 2, 3, 4, 5};
var filtered = otherNums.Where(num => nums.Contains(num));
foreach (var num in filtered)
{
Console.WriteLine(num);
}
}
private static IEnumerable<int> GetNums()
{
yield return 4;
yield return 2;
}
这怎么不会导致IEnumerable的多个枚举?
答案 0 :(得分:2)
这会导致 枚举的多个枚举。
如果我将您的代码更改为:
otherNums
...然后我可以得到以下输出:
1? 4! 2! 2? 4! 2! 2 3? 4! 2! 4? 4! 4 5? 4! 2!
您可以看到,对于每个正在测试的nums
,每次都会运行GetNums
(4
)。在测试nums
时,它只需要.Where
的第一个数字,否则它将完全迭代5次。
如果您想知道为什么foreach
和otherNums
两者不通过.Where
进行迭代,那是因为{{1}使用延迟执行模型运行 - 仅当您执行foreach
或类似.ToList()
执行的操作时才会运行。
答案 1 :(得分:0)
Resharper可能建议将参数的类型更改为IEnumerable
,因为没有调用者会传递其他类型而不是(派生自)IEnumerable
,Resharper建议使用最简单的类型。
ICollection
只向IEnumerable
添加了一些属性和方法,最重要的是Count
属性。
根据this table,GetEnumerator()
方法对于实现ICollection
的大多数类具有相同的复杂性。