链接方法

许多 LINQ 函数都在 IEnumerable<TSource> 上运行,并且还返回 IEnumerable<TResult>。类型参数 TSourceTResult 可能会或可能不会引用相同的类型,具体取决于所讨论的方法和传递给它的任何函数。

这方面的一些例子是

public static IEnumerable<TResult> Select<TSource, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, TResult> selector
)

public static IEnumerable<TSource> Where<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, int, bool> predicate
)

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector
)

虽然某些方法链接可能需要在继续之前处理整个集合,但 LINQ 通过使用 yield return MSDN 来利用延迟执行,该 MSDN 在后台创建 Enumerable 和 Enumerator。在 LINQ 中链接的过程本质上是为原始集合构建一个可枚举(迭代器) - 这是延迟的 - 直到通过枚举枚举来实现****

这允许这些函数流畅地链接 wiki ,其中一个函数可以直接对另一个函数的结果起作用。这种代码风格可用于在单个语句中执行许多基于序列的操作。

例如,可以将 SelectWhereOrderBy 组合在一个语句中对序列进行转换,过滤和排序。

var someNumbers = { 4, 3, 2, 1 };

var processed = someNumbers
        .Select(n => n * 2)   // Multiply each number by 2
        .Where(n => n != 6)   // Keep all the results, except for 6
        .OrderBy(n => n);     // Sort in ascending order

输出:

2
4
8

.NET 小提琴现场演示

扩展和返回泛型 IEnumerable<T> 类型的任何函数都可以在单个语句中用作链接子句。这种流畅的编程风格很强大,在创建自己的扩展方法时应该考虑到这一点。