C# 这如何不导致IEnumerable的多个枚举?

C# 这如何不导致IEnumerable的多个枚举?,c#,linq,C#,Linq,我最初将参数类型设置为ICollection,因为我认为在IEnumerable的多个枚举中会遇到问题。但是,Resharper建议我可以将参数类型转换为IEnumerable。我最后做了一个测试来再次检查,它似乎工作得很好: private static void Main(string[] args) { var nums = GetNums(); MultipleEnumerations(nums); Console.Read

我最初将参数类型设置为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;
    }
private static void Main(字符串[]args)
{
var nums=GetNums();
多重计算(NUM);
Console.ReadLine();
}
私有静态void倍数(IEnumerable nums)
{
var otherNums=新列表{1,2,3,4,5};
var filtered=otherNums.Where(num=>nums.Contains(num));
foreach(过滤中的var num)
{
控制台写入线(num);
}
}
私有静态IEnumerable GetNums()
{
收益率4;
收益率2;
}

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

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

ICollection
仅向其派生的
IEnumerable
添加一些属性和方法,最重要的是
Count
属性


据介绍,
GetEnumerator()
方法对于实现
ICollection

的大多数类具有相同的复杂性,Resharper可能建议将参数的类型更改为
IEnumerable
,因为没有调用方会传递(派生自)
IEnumerable
以外的其他类型,Resharper建议使用最简单的类型

ICollection
仅向其派生的
IEnumerable
添加一些属性和方法,最重要的是
Count
属性


根据,对于大多数实现
ICollection

的类来说,
GetEnumerator()
方法具有相同的复杂性,这确实会导致对一个可枚举项进行多次枚举

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

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;
}
private static void multiplenumerations(IEnumerable nums)
{
var otherNums=新列表{1,2,3,4,5};
var filtered=otherNums.Where(num=>
{
WriteLine(“{0}?”,num);
返回nums.Contains(num);
});
foreach(过滤中的var num)
{
控制台写入线(num);
}
}
私有静态IEnumerable GetNums()
{
控制台。WriteLine(“4!”);
收益率4;
控制台。WriteLine(“2!”);
收益率2;
}
…然后我可以得到以下输出:

1? 4! 2! 2? 4! 2! 2 3? 4! 2! 4? 4! 4 5? 4! 2! 1. 4. 2. 2. 4. 2. 2. 3. 4. 2. 4. 4. 4. 5. 4. 2. 您可以看到,对于正在测试的每个
otherNums
,它每次都运行
nums
(即
GetNums
)。当测试
4
时,它只取第一个
num
,但在其他情况下,它将完全迭代5次


如果你想知道为什么
。Where
foreach
这两个
都没有通过
其他
进行迭代,那是因为
。Where
是使用延迟执行模型运行的-只有当你执行
foreach
或类似
的操作时,ToList()
它执行。

这确实会导致一个可枚举项的多个枚举

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

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;
}
private static void multiplenumerations(IEnumerable nums)
{
var otherNums=新列表{1,2,3,4,5};
var filtered=otherNums.Where(num=>
{
WriteLine(“{0}?”,num);
返回nums.Contains(num);
});
foreach(过滤中的var num)
{
控制台写入线(num);
}
}
私有静态IEnumerable GetNums()
{
控制台。WriteLine(“4!”);
收益率4;
控制台。WriteLine(“2!”);
收益率2;
}
…然后我可以得到以下输出:

1? 4! 2! 2? 4! 2! 2 3? 4! 2! 4? 4! 4 5? 4! 2! 1. 4. 2. 2. 4. 2. 2. 3. 4. 2. 4. 4. 4. 5. 4. 2. 您可以看到,对于正在测试的每个
otherNums
,它每次都运行
nums
(即
GetNums
)。当测试
4
时,它只取第一个
num
,但在其他情况下,它将完全迭代5次


如果你想知道为什么
。Where
foreach
这两个
都没有通过
其他
进行迭代,那是因为
。Where
是使用延迟执行模型运行的-只有当你执行
foreach
或类似
的操作时,ToList()
它执行。

otherNums
是一个列表。您能解释一下为什么您认为它会导致多个枚举吗?--在尝试之后,您是对的:如果不具体化数组,您将执行多个枚举。也许这只是一个R#无法很好地检测到的场景。为了确定otherNums列表中的数字是否在nums IEnumerable中,它必须迭代nums中的所有元素。由于我们对其他nums中的每个int进行检查,我认为这将是多个枚举。代码运行没有问题并不意味着没有多个枚举。您可以根据需要多次枚举它,Resharper会生成警告,因为在许多情况下,它会对性能造成不良影响(例如,如果IEnumerable是复杂Linq查询的结果,因为重新枚举意味着重新执行查询。最好将结果缓存在集合中)
otherNums
是一个列表。您能解释一下为什么您认为它会导致多次枚举吗?--在尝试之后,您是对的:如果不具体化数组,您将执行多个枚举。也许这只是一个R#无法很好地检测到的场景。为了确定otherNums列表中的数字是否在nums IEnumerable中,它必须迭代nums中的所有元素。自从w