LINQ系列:Linq to Object限制操作符
1. Where
限制操作符Where用于过滤序列,按照提供的逻辑对序列中的数据进行过滤。Where可以出现多次。
1.1 原型定义
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate);
1.2 单个限制条件
var products = from p in context.Products where p.UnitPrice > 10m select p;
var products = context.Products .Where(p => p.UnitPrice > 10m);
Func<Product, bool> filter = delegate(Product p) { return p.UnitPrice > 10m; }; var query = context.Products .Where(filter) .Select(p => new { p.ProductID, p.ProductName });
// using System.Linq; int[] fibonacci = new int[] { 1, 1, 2, 3, 5, 8, 13, 21 }; IEnumerable<int> query = Enumerable.Where(fibonacci, f => f > 5); query.ToList().ForEach(f => { Console.WriteLine(f); });
1.3 多个过滤条件
var products = from p in context.Products where p.UnitPrice > 10m && p.ProductName.StartsWith("LINQ") select p;
var products = context.Products .Where(p => p.UnitPrice > 10m && p.ProductName.StartsWith("LINQ"));
var expr = context.Products .Where(p => p.UnitPrice > 10m) .Where(p => p.ProductName.StartsWith("LINQ"));
1.4 Lambda多参数表达式
int[] fibonacci = new int[] { 1, 1, 2, 3, 5, 8, 13, 21 }; var expr = fibonacci.Where((f, index) => f > 1 && index > 3); foreach (var item in expr) { Console.WriteLine(item); }
1.5 自定义实现
LINQ是在C#3.0出现的,在C#2.0及之前没有LINQ的支持,接下来为LINQ Where操作符的自定义实现。
C#2.0实现方式:
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
using System; using System.Collections.Generic; using System.Text; namespace Northwind.CustomLINQExtension { public static class CustomLINQExtension { public delegate TResult Func<in T, out TResult>(T arg); public static IEnumerable<TSource> Where<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate) { foreach (TSource element in source) { if (predicate(element)) { yield return element; } } } } }
using System; using System.Collections.Generic; using System.Text; namespace Northwind.CustomLINQExtension { class Program { static void Main(string[] args) { int[] fibonacci = new int[] { 1, 1, 2, 3, 5, 8, 13, 21 }; IEnumerable<int> expr = CustomLINQExtension.Where(fibonacci, (delegate(int i) { return i > 3; })); foreach (int item in expr) { Console.WriteLine(item); } } } }
由于在C#2.0中没有扩展方法,调用实现的自定义扩展类需要使用类名。
在C#3.0中增加了扩展方法,在C#3.0自定义LINQ Where限制条件,不使用系统LINQ自带。
using System; using System.Collections.Generic; using System.Text; namespace Northwind.CustomLINQExtension { public static class CustomLINQExtension { public delegate TResult Func<in T, out TResult>(T arg); public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { foreach (TSource element in source) { if (predicate(element)) { yield return element; } } } } }
using System; using System.Collections.Generic; using System.Text; namespace Northwind.CustomLINQExtension { class Program { static void Main(string[] args) { int[] fibonacci = new int[] { 1, 1, 2, 3, 5, 8, 13, 21 }; IEnumerable<int> expr = fibonacci.Where(delegate(int i) { return i > 3; }); foreach (int item in expr) { Console.WriteLine(item); } } } }