LINQ 的推导和原理:委托、Lambda 与延迟执行

为啥要学 LINQ

让数据处理变得简单

Linq的使用 C#编程之Linq-语言集成查询

委托

1、委托是可以指向方法的类型,调用委托变量时执行的就是变量指向的方法。
2、.NET中定义了泛型委托 Action(无返回值)和 Func(有返回值),所以一般不用自定义委托类型。

static void Main(string[] args)
{
    DelegateTest delegateTest = DelegateFun;
    delegateTest();
}

static void DelegateFun()
{
    Console.WriteLine("被委托调用");
}

// 委托声明 必须与被调用方法的返回值类型、参数类型、参数个数一致
delegate void DelegateTest();

Lambda 表达式怎么来的

Lambda 表达式推导

static void Main(string[] args)
{
    Action action = delegate ()
    {
        Console.WriteLine("匿名方法");
    };
    action();

    Action<int, int> action1 = delegate (int n, int m)
    {
        Console.WriteLine($"n={n},m={m}");
    };
    action1(2, 3);

    Func<int, int, int> func = delegate (int n, int m)
    {
        return n + m;
    };
    Console.WriteLine(func(1, 2));

    /* lambda 表达式 推导*/
    Func<int, int, int> func1 = (int n, int m) =>
     {
         return n + m;
     };

    // 无返回值
    Action action2 = () => Console.WriteLine("匿名方法");

    // 有返回值
    Func<int, int, int> func3 = (n, m) => n + m;

    // 只有一个参数,且无返回值
    Action<string> action3 = s => Console.WriteLine(s);

    // 有一个参数,有返回值
    Func<int, bool> func4 = n => n > 3;

    // lambda 反推 匿名方法 
    Func<int, bool> f1 = i => i > 5;

    Func<int, bool> f2 = delegate (int i)
    {
        return i > 5;
    };
}

揭秘 LINQ

Linq 使用时 用的是 System.Linq 程序集中的扩展方法
下面模拟 System.Linq 程序集中的方法 实现查询出数据中大于10的数字
因为不是扩展方法所以调用时有些许差别

using System;
using System.Collections.Generic;
using System.Linq;

static void Main(string[] args)
{
    int[] nums = new int[] { 12, 23, 3, 4, 2, 234, 123 };

    // 自定义实现
    IEnumerable<int> result = MyWhere(nums, a => a > 10);
    foreach (var item in result)
    {
        Console.WriteLine(item);
    }

    IEnumerable<int> result2 = MyWhere2(nums, a => a > 10);
    foreach (var item in result2)
    {
        Console.WriteLine(item);
    }

    // Linq
    var data = nums.Where(x => x > 10);
    foreach (var item in data)
    {
        Console.WriteLine(item);
    }
}

// 实现方式1
static IEnumerable<int> MyWhere(IEnumerable<int> items, Func<int, bool> func)
{
    List<int> list = new List<int>();
    foreach (int item in items)
    {
        if (func(item))
        {
            list.Add(item);
        }
    }
    return list;
}

// 实现方式2:使用迭代器按需返回
static IEnumerable<int> MyWhere2(IEnumerable<int> items, Func<int, bool> func)
{
    foreach (int item in items)
    {
        if (func(item))
        {
            yield return item;
        }
    }
}

同步整理说明

上面的 MyWhere 会立即遍历并创建列表;MyWhere2 使用 yield return,在枚举时按需执行,不会预先保存全部匹配结果。延迟执行并不意味着在所有场景下都更快,重复枚举也可能重复计算。本文演示的是 LINQ to Objects 的过滤思路,不涉及数据库查询提供程序。

同步时修正了第二段遍历误用 result 的笔误,改为遍历 result2。各段 Main 是独立示例,分别放入控制台程序运行。

参考:Microsoft Learn:延迟执行。


本文为本人原创文章,同步自 CSDN 原文。同步时修正笔误,并由 AI 辅助补充延迟执行说明。

posted @ 2026-10-06 20:18  JacePan  阅读(4)  评论(0)    收藏  举报