C# 匿名方法与 Lambda 表达式全解析

在日常 C# 开发中,我们经常遇到这样的问题:

"我想把一个方法作为参数传递给另一个方法,但不想单独创建一个命名方法。"

这个时候,匿名方法(Anonymous Methods)Lambda 表达式就派上用场了。它们不仅能让代码更简洁,还能处理临时逻辑、事件回调甚至 LINQ 查询。本文将带你全面理解它们的用法、区别和最佳实践。


1️⃣ 委托与匿名方法概念

在深入之前,我们先回顾一下 委托(Delegate) 的概念:

委托是一种类型安全的函数指针,它可以引用与其签名相同的方法,通过委托对象调用方法。

匿名方法是没有名字的方法,可以直接将代码块作为委托实现,避免创建额外的命名方法。

匿名方法示例

csharp 复制代码
using System;

delegate void NumberChanger(int n);

class Program
{
    static void Main()
    {
        NumberChanger nc = delegate(int x)
        {
            Console.WriteLine("Anonymous Method: {0}", x);
        };

        nc(10); // 输出:Anonymous Method: 10
    }
}

匿名方法使用 delegate 关键字定义,方法体可直接访问外部变量,适合一次性、临时逻辑。


2️⃣ Lambda 表达式简介

C# 2.0 之后,引入了 Lambda 表达式,它是匿名方法的升级版,更简洁直观,并广泛应用于 LINQ 查询和委托操作。

Lambda 语法

csharp 复制代码
(parameters) => expression
// 或者
(parameters) => { statements; }

Lambda 示例

csharp 复制代码
using System;

delegate void NumberChanger(int n);

class Program
{
    static void Main()
    {
        NumberChanger nc = x => Console.WriteLine($"Lambda Expression: {x}");
        nc(10); // 输出:Lambda Expression: 10
    }
}

优势

  • 参数类型可省略,编译器自动推断
  • 支持闭包,能够访问外部变量
  • 与 LINQ 结合,代码极度简洁

3️⃣ 匿名方法 vs Lambda 表达式

特性 匿名方法 Lambda 表达式
语法 delegate(params) { statements; } (params) => expression(params) => { statements; }
参数类型 可指定,也可省略 可省略,自动推断
简洁性 相对冗长 简洁明了
LINQ 支持 不常用 广泛用于 LINQ 查询
闭包支持 支持 支持
性能 略慢(编译器生成内部类) 高效(编译器优化,特别是短小 Lambda)

总结:Lambda 表达式是匿名方法的现代替代方案,更适合函数式编程和 LINQ 场景。


4️⃣ 实战示例:事件处理与集合操作

匿名方法作为事件处理程序

csharp 复制代码
Button button = new Button();
button.Click += delegate(object sender, EventArgs e)
{
    Console.WriteLine("Button clicked via Anonymous Method!");
};

Lambda 表达式作为事件处理程序

csharp 复制代码
Button button = new Button();
button.Click += (sender, e) => Console.WriteLine("Button clicked via Lambda!");

Lambda 结合 LINQ 过滤集合

csharp 复制代码
int[] numbers = { 1, 2, 3, 4, 5, 6 };
var evenNumbers = numbers.Where(n => n % 2 == 0);

foreach (var num in evenNumbers)
{
    Console.WriteLine(num); // 输出 2 4 6
}

对比可见,Lambda 使集合处理更简洁高效,匿名方法写法冗长且可读性差。


5️⃣ 闭包与 Lambda 的妙用

Lambda 支持访问外部变量:

csharp 复制代码
int factor = 5;
Func<int, int> multiply = x => x * factor;

Console.WriteLine(multiply(3)); // 输出 15

这就是所谓的闭包(Closure),可以让 Lambda 捕获并使用外部变量,方便处理动态逻辑。


6️⃣ 总结与开发建议

  • 匿名方法:适合旧版 C# 或简单一次性逻辑

  • Lambda 表达式:现代开发首选,语法简洁,适合 LINQ、事件、闭包

  • 实际应用建议

    • 临时事件处理 → Lambda
    • LINQ 查询 → Lambda
    • 复杂闭包逻辑 → Lambda 或匿名方法均可

💡 面试技巧:了解匿名方法和 Lambda 的差异,能讲清闭包和委托的关系,是常考点。


参考示例:整合匿名方法与 Lambda

csharp 复制代码
using System;
using System.Linq;

delegate void NumberChanger(int n);

class Program
{
    static int num = 10;

    static void AddNum(int p)
    {
        num += p;
        Console.WriteLine("Named Method: {0}", num);
    }

    static void Main()
    {
        // 匿名方法
        NumberChanger nc1 = delegate(int x) { Console.WriteLine("Anonymous Method: {0}", x); };
        nc1(10);

        // Lambda 表达式
        NumberChanger nc2 = x => Console.WriteLine($"Lambda Expression: {x}");
        nc2(20);

        // LINQ 示例
        int[] numbers = { 1, 2, 3, 4, 5 };
        var squares = numbers.Select(n => n * n);
        Console.WriteLine("Squares: " + string.Join(", ", squares));

        // 委托调用命名方法
        NumberChanger nc3 = new NumberChanger(AddNum);
        nc3(5);
    }
}

运行结果:

复制代码
Anonymous Method: 10
Lambda Expression: 20
Squares: 1, 4, 9, 16, 25
Named Method: 15
相关推荐
筱璦9 小时前
期货软件开发 - C# 调用 HQChart 指标计算 C++ 动态库
c++·microsoft·c#
武藤一雄10 小时前
C# 异常(Exception)处理避坑指南
windows·microsoft·c#·.net·.netcore·鲁棒性
武藤一雄13 小时前
WPF中ViewModel之间的5种通讯方式
开发语言·前端·microsoft·c#·wpf
雨浓YN13 小时前
OPC UA 通讯开发笔记 - 基于Opc.Ua.Client
笔记·c#
我是唐青枫14 小时前
C#.NET TPL Dataflow 深入解析:数据流管道、背压控制与实战取舍
c#·.net
SunnyDays101116 小时前
如何使用 C# 创建、修改和删除 Excel 中的 VBA 宏(无需Microsoft Excel)
c#·excel·vba宏·创建vba宏·修改vba宏·删除vba宏
唐青枫17 小时前
C#.NET gRPC 深入解析:Proto 定义、流式调用与服务间通信取舍
c#·.net
水深00安东尼18 小时前
C# 鼠标点击小游戏
c#
波波00718 小时前
每日一题:C#中using的三种用法
开发语言·c#
游乐码18 小时前
c#万物之父
开发语言·c#