I get the sequence number 0 ~ 2 with IEnumerable and when I print the result. The IEnumerable
and IEnumerable.ToList()
result is difference.
void Main()
{
var numbers = GetNumbers();
Print(numbers);
/*
Return: 0
Print: 0
Return: 1
Print: 1
Return: 2
Print: 2
Return: 0
Return: 1
Return: 2
Total: 3
*/
Print(numbers.ToList());
/*
Return: 0
Return: 1
Return: 2
Print: 0
Print: 1
Print: 2
Total: 3
*/
}
void Print(IEnumerable<int> numbers) {
foreach(var number in numbers)
{
Console.WriteLine($"Print: {number}");
}
Console.WriteLine($"Total: {numbers.Count()}");
}
IEnumerable<int> GetNumbers()
{
return Enumerable.Range(0, 3)
.Select(n =>
{
Console.WriteLine($"Return: {n}");
return n;
});
}
Seems the pure IEnumerable the linq Select
function is call twice when execute the IEnumerable.Count()
.
What happened to this?
When you call numbers.Count()
, you're enumerating the IEnumerable
again. Because the IEnumerable is enumerated twice, the Return lines are each printed twice.
The list conversion enumerates the IEnumerable
to build the list, but after that, only the resulting List<int>
is used by Print
. When .Count()
is called on the List, which just returns the built-in Count
property of List<int>
and doesn't enumerate anything.