I originally set my parameter type to be ICollection because I thought I would run into issues with multiple enumerations of an IEnumerable. However, Resharper suggested that I can convert the parameter type to be an IEnumerable. I ended up making a test to double check and it seems to work fine:
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;
}
How does this not lead to multiple enumerations of an IEnumerable?
This does lead to multiple enumerations of an enumerable.
If I change your code to this:
private static void MultipleEnumerations(IEnumerable<int> nums)
{
var otherNums = new List<int> { 1, 2, 3, 4, 5 };
var filtered = otherNums.Where(num =>
{
Console.WriteLine("{0}?", num);
return nums.Contains(num);
});
foreach (var num in filtered)
{
Console.WriteLine(num);
}
}
private static IEnumerable<int> GetNums()
{
Console.WriteLine("4!");
yield return 4;
Console.WriteLine("2!");
yield return 2;
}
...then I can get the following output:
1? 4! 2! 2? 4! 2! 2 3? 4! 2! 4? 4! 4 5? 4! 2!
You can see that for each otherNums
being tested it is running through nums
(which is GetNums
) each time. When testing 4
it only takes the first number of nums
, but otherwise it is iterating it fully 5 times.
If you're wondering why .Where
and the foreach
both don't iterate thru the otherNums
it is because .Where
is run with a deferred execution model - it's only when you do a foreach
or something like .ToList()
that it executes.
Resharper probably suggested changing the type of the parameter to IEnumerable
, because there is no caller who would pass other type than (derived from) IEnumerable
, Resharper suggested the simplest type.
ICollection
adds only a few properties and methods to IEnumerable
from which it derives, most importantly the Count
property.
According to this table , the GetEnumerator()
method has the same complexity for most classes implementing ICollection
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.