c# - 将 LINQ 查询的枚举限制为仅一个
问题描述
我有一个不应多次枚举的 LINQ 查询,并且我想避免错误地枚举它两次。我可以使用任何扩展方法来确保我免受此类错误的影响吗?我正在考虑这样的事情:
var numbers = Enumerable.Range(1, 10).OnlyOnce();
Console.WriteLine(numbers.Count()); // shows 10
Console.WriteLine(numbers.Count()); // throws InvalidOperationException: The query cannot be enumerated more than once.
我想要这个功能的原因是因为我有一个可枚举的任务,旨在逐步实例化和运行任务,同时在控制下缓慢枚举。我已经犯了两次运行任务的错误,因为我忘记了它是一个不同的可枚举而不是数组。
var tasks = Enumerable.Range(1, 10).Select(n => Task.Run(() => Console.WriteLine(n)));
Task.WaitAll(tasks.ToArray()); // Lets wait for the tasks to finish...
Console.WriteLine(String.Join(", ", tasks.Select(t => t.Id))); // Lets see the completed task IDs...
// Oups! A new set of tasks started running!
解决方案
我想避免错误地枚举它两次。
如果它被枚举两次,你可以用一个集合来包装这个集合。
例如:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp8
{
public static class EnumExtension
{
class OnceEnumerable<T> : IEnumerable<T>
{
IEnumerable<T> col;
bool hasBeenEnumerated = false;
public OnceEnumerable(IEnumerable<T> col)
{
this.col = col;
}
public IEnumerator<T> GetEnumerator()
{
if (hasBeenEnumerated)
{
throw new InvalidOperationException("This collection has already been enumerated.");
}
this.hasBeenEnumerated = true;
return col.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public static IEnumerable<T> OnlyOnce<T>(this IEnumerable<T> col)
{
return new OnceEnumerable<T>(col);
}
}
class Program
{
static void Main(string[] args)
{
var col = Enumerable.Range(1, 10).OnlyOnce();
var colCount = col.Count(); //first enumeration
foreach (var c in col) //second enumeration
{
Console.WriteLine(c);
}
}
}
}
推荐阅读
- javascript - 分页后事件侦听器在第二页上不起作用
- yaml - 如何对 yaml 进行 lint 并忽略多个“depends_on”?
- c - 二叉搜索树插入程序显示分段错误
- appium - Codeceptjs 滑动功能
- python-3.x - 如何在python中正确导入子包?
- java - 在 Firebase 中检索和更新子数据
- excel - ExcelVBA_CurrentValuecu_Filter?
- r - 总结满足条件的第一行
- react-native - 为什么我在使用“react-native run-android”构建 android 时收到此错误
- oracle - 通过电子邮件在 apex Oracle 中确认创建记录