C# 为什么 IEnumerable 和 IEnumerable.ToList() 打印的结果不同?

C# Why IEnumerable and IEnumerable.ToList() print their result is difference?

我用 IEnumerable 得到序列号 0 ~ 2,当我打印结果时。 IEnumerableIEnumerable.ToList() 结果不同。

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;
        });
}

似乎纯 IEnumerable linq Select 函数在执行 IEnumerable.Count().

时调用了两次

这是怎么回事?

当您调用 numbers.Count() 时,您将再次枚举 IEnumerable。因为 IEnumerable 被枚举了两次,所以 Return 行每行打印两次。

列表转换枚举IEnumerable来构建列表,但之后,只有List<int>Print使用。当 .Count() 在 List 上被调用时,它只是 returns List<int> 的内置 Count 属性 而没有枚举任何东西。