17370845950

C# 匿名方法使用方法 C#如何创建和使用匿名方法
C#匿名方法是C# 2.0引入的无名内联方法,以delegate关键字定义,需绑定具体委托类型;它支持多语句和变

量捕获但不支持async,而lambda更简洁、优化更好且支持表达式树和异步。

什么是 C# 匿名方法?它和 lambda 表达式有什么区别?

匿名方法是 C# 2.0 引入的语法,用于内联定义没有名称的方法体,直接作为委托实例传入。它不是“更高级的 lambda”,而是更底层、更冗长的写法——delegate 关键字开头,没有返回类型声明(由委托类型推导),也没有参数类型显式标注(也可省略,但需匹配委托签名)。

x => x.ToString() 这类 lambda 相比,匿名方法更适合需要多语句、局部变量捕获或明确空参数列表的场景;但编译器对 lambda 的优化更好,现代 C# 项目中几乎不再主动写匿名方法。

如何用 delegate 关键字创建匿名方法?

必须绑定到兼容的委托类型。常见错误是直接写 delegate { } 而不赋值给变量或传参,这会导致编译失败:“无法将匿名方法转换为类型‘object’”。

  • 必须指定委托类型,例如 ActionFunc 或自定义委托
  • 参数列表可省略(此时调用时不能传参),也可显式写出(类型可省略,如 delegate(int x) { return x > 0; }
  • 返回值必须与委托声明一致;若委托返回 void,方法体内不能有 return 值语句
Action sayHello = delegate { Console.WriteLine("Hello"); };
Func isPositive = delegate(int n) { return n > 0; };

匿名方法怎么捕获外部变量?要注意什么?

可以访问所在作用域的局部变量和参数,但要注意闭包生命周期问题:变量会延长至委托实例存活期,而非原始作用域结束时销毁。

典型陷阱是循环中创建多个匿名方法却共用同一个循环变量:

var actions = new List();
for (int i = 0; i < 3; i++) {
    actions.Add(delegate { Console.WriteLine(i); });
}
foreach (var a in actions) a(); // 输出:3, 3, 3(不是 0,1,2)

解决办法是在循环内复制变量:int localI = i;,再在匿名方法中使用 localI

什么时候该用匿名方法而不是 lambda?

极少情况。只有当你要写多语句逻辑且不想升级到 C# 3.0+ 语法,或对接旧版 API 强制要求 delegate 形式时才用。Lambda 在所有现代场景下都更简洁、可读性更高、支持表达式树(如 LINQ to Entities)。

一个真实但边缘的例子:WinForms 中老式事件订阅有时仍见 button.Click += delegate { ... };,但这只是为了兼容极老代码模板;新项目一律用 += (s,e) => { ... }

真正容易被忽略的是:匿名方法不支持异步(async delegate 是非法语法),要异步必须用 lambda + async 修饰符。