C#匿名方法是C# 2.0引入的无名内联方法,以delegate关键字定义,需绑定具体委托类型;它支持多语句和变量捕获但不支持async,而lambda更简洁、优化更好且支持表达式树和异步。
匿名方法是 C# 2.0 引入的语法,用于内联定义没有名称的方法体,直接作为委托实例传入。它不是“更高级的 lambda”,而是更底层、更冗长的写法——delegate 关键字开头,没有返回类型声明(由委托类型推导),也没有参数类型显式标注(也可省略,但需匹配委托签名)。
和 x => x.ToString() 这类 lambda 相比,匿名方法更适合需要多语句、局部变量捕获或明确空参数列表的场景;但编译器对 lambda 的优化更好,现代 C# 项目中几乎不再主动写匿名方法。
必须绑定到兼容的委托类型。常见错误是直接写 delegate { } 而不赋值给变量或传参,这会导致编译失败:“无法将匿名方法转换为类型‘object’”。
Action、Func 或自定义委托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。
极少情况。只有当你要写多语句逻辑且不想升级到 C# 3.0+ 语法,或对接旧版 API 强制要求 delegate 形式时才用。Lambda 在所有现代场景下都更简洁、可读性更高、支持表达式树(如 LINQ to Entities)。
一个真实但边缘的例子:WinForms 中老式事件订阅有时仍见 button.Click += delegate { ... };,但这只是为了兼容极老代码模板;新项目一律用 += (s,e) => { ... }。
真正容易被忽略的是:匿名方法不支持异步(async delegate 是非法语法),要异步必须用 lambda + async 修饰符。