为 IEnumerableT 构建自己的 Linq 运算符
Linq 的一大优点是它易于扩展。你只需要创建一个参数为 IEnumerable<T>
的扩展方法 。
public namespace MyNamespace
{
public static class LinqExtensions
{
public static IEnumerable<List<T>> Batch<T>(this IEnumerable<T> source, int batchSize)
{
var batch = new List<T>();
foreach (T item in source)
{
batch.Add(item);
if (batch.Count == batchSize)
{
yield return batch;
batch = new List<T>();
}
}
if (batch.Count > 0)
yield return batch;
}
}
}
此示例将 IEnumerable<T>
中的项目拆分为固定大小的列表,最后一个列表包含其余项目。注意使用 this
关键字如何将应用扩展方法的对象作为初始参数传入(参数 source
)。然后 yield
关键字用于在继续从该点执行之前输出输出 IEnumerable<T>
中的下一个项目(请参阅 yield 关键字 )。
此示例将在你的代码中使用,如下所示:
//using MyNamespace;
var items = new List<int> { 2, 3, 4, 5, 6 };
foreach (List<int> sublist in items.Batch(3))
{
// do something
}
在第一个循环中,子列表将是 {2, 3, 4}
,而在第二个 {5, 6}
上。
自定义 LinQ 方法也可以与标准 LinQ 方法结合使用。例如:
//using MyNamespace;
var result = Enumerable.Range(0, 13) // generate a list
.Where(x => x%2 == 0) // filter the list or do something other
.Batch(3) // call our extension method
.ToList() // call other standard methods
此查询将返回批量分组的偶数,大小为 3:{0, 2, 4}, {6, 8, 10}, {12}
请记住,你需要 using MyNamespace;
行才能访问扩展方法。