这怎么不导致IEnumerable的多个枚举?

时间:2016-02-25 20:22:03

标签: c# linq

我最初将我的参数类型设置为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的多个枚举?

2 个答案:

答案 0 :(得分:2)

这会导致 枚举的多个枚举。

如果我将您的代码更改为:

otherNums

...然后我可以得到以下输出:

1?
4!
2!
2?
4!
2!
2
3?
4!
2!
4?
4!
4
5?
4!
2!

您可以看到,对于每个正在测试的nums,每次都会运行GetNums4)。在测试nums时,它只需要.Where的第一个数字,否则它将完全迭代5次。

如果您想知道为什么foreachotherNums 两者不通过.Where进行迭代,那是因为{{1}使用延迟执行模型运行 - 仅当您执行foreach或类似.ToList()执行的操作时才会运行。

答案 1 :(得分:0)

Resharper可能建议将参数的类型更改为IEnumerable,因为没有调用者会传递其他类型而不是(派生自)IEnumerable,Resharper建议使用最简单的类型。

ICollection只向IEnumerable添加了一些属性和方法,最重要的是Count属性。

根据this tableGetEnumerator()方法对于实现ICollection的大多数类具有相同的复杂性。