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