LINQ系列:Linq to Object限制操作符

libingql發表於2014-10-21

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);
            }
        }
    }
}

相關文章