【问题标题】:C# Why IEnumerable and IEnumerable.ToList() print their result is difference?C# 为什么 IEnumerable 和 IEnumerable.ToList() 打印它们的结果不同?
【发布时间】:2022-01-14 03:22:13
【问题描述】:

我用 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.Count()时,似乎纯IEnumerable linq Select函数被调用了两次。

这是怎么回事?

【问题讨论】:

  • 枚举被枚举多次(每次循环),这通过枚举(选择)的中的副作用注意到。这在其他情况下也可能有问题,例如返回 Guid.NewGuid 值。

标签: c# list linq ienumerable


【解决方案1】:

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

列表转换枚举IEnumerable 来构建列表,但之后,Print 仅使用生成的List&lt;int&gt;。在 List 上调用.Count() 时,它只返回List&lt;int&gt; 的内置Count 属性,不枚举任何内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 2021-12-02
    • 1970-01-01
    相关资源
    最近更新 更多