鉴于以下情况:
var nums = GetNums();
Console.WriteLine(nums.Any());
Console.WriteLine(string.Join(", ", nums));
static IEnumerable<int> GetNums()
{
yield return 1;
yield return 2;
yield return 3;
}
ReSharper 将此标记为“可能的多重枚举”。然而,运行它会产生
True
1, 2, 3
证明没有跳过任何元素。在没有谓词的情况下调用 Any 时,情况总是如此吗?或者在某些情况下这会产生不必要的副作用?
这完全取决于
IEnumerable<T>
的支持者及其运作方式。例如,BlockingCollection<T>
允许您获得一个“消耗可枚举”,它只产生一次项目。
示例代码:
var blockingCollection = new BlockingCollection<int>();
blockingCollection.Add(1);
blockingCollection.Add(2);
blockingCollection.Add(3);
blockingCollection.CompleteAdding();
var nums = blockingCollection.GetConsumingEnumerable();
Console.WriteLine(nums.Any());
Console.WriteLine(string.Join(", ", nums));
Console.WriteLine(nums.Any());
输出:
True
2, 3
False