C# 匿名方法
本章节全面系统地讲解 C# 匿名方法(Anonymous Methods),并搭配实例和高级用法帮助你理解和掌握,含语法、实例、委托、闭包、对比 Lambda。
1. 什么是匿名方法?
匿名方法是在不显式声明方法名称的情况下,直接定义方法体并将其赋给一个委托的方式。
🔹 语法形式:
delegate(int x, int y)
{
return x + y;
};
它实际上是 C# 2.0 引入的,用于增强对委托的支持,后来被 lambda 表达式进一步简化和取代。
2. 基础示例:匿名方法赋值给委托
using System;
public delegate void PrintDelegate(string message);
class Program
{
static void Main()
{
PrintDelegate printer = delegate (string msg)
{
Console.WriteLine("打印内容:" + msg);
};
printer("Hello, 匿名方法");
}
}
3. 匿名方法 vs Lambda 表达式
| 特性 | 匿名方法 | Lambda 表达式 |
|---|---|---|
| 引入版本 | C# 2.0 | C# 3.0 |
是否有 delegate 关键词 | 是 | 否 |
| 是否必须指定参数类型 | 否(可选) | 否(可选) |
| 是否简洁 | 略冗长 | 更简洁优雅 |
🔹 Lambda 替代写法:
PrintDelegate printer = msg => Console.WriteLine("打印内容:" + msg);
4. 使用匿名方法做事件处理器
button.Click += delegate (object sender, EventArgs e)
{
Console.WriteLine("按钮被点击");
};
5. 匿名方法中的闭包支持
匿名方法可捕获并访问外部变量(即闭包):
int count = 0;
Action increment = delegate
{
count++;
Console.WriteLine("Count = " + count);
};
increment(); // Count = 1
increment(); // Count = 2
✅ 闭包中变量会被“捕获”为引用,而不是值的副本。
6. 带返回值的匿名方法
Func<int, int, int> sum = delegate (int a, int b)
{
return a + b;
};
Console.WriteLine(sum(3, 5)); // 输出 8
7. 多参数匿名方法(用于 LINQ)
var nums = new[] { 1, 2, 3, 4 };
var evens = Array.FindAll(nums, delegate (int x)
{
return x % 2 == 0;
});
foreach (var n in evens) Console.WriteLine(n); // 2, 4
8. 高级:泛型委托 + 匿名方法
Func<string, string> formatter = delegate (string name)
{
return $"你好,{name}!";
};
Console.WriteLine(formatter("张三")); // 你好,张三!
9. 匿名方法不能做什么?
- ❌ 无法访问
ref和out参数 - ❌ 不能用于异步
async/await(建议用 lambda) - ❌ 不适用于结构体中的委托捕获值类型变量(避免装箱)
10. 推荐场景总结
| 场景 | 推荐用法 |
|---|---|
| 简单事件绑定 | 匿名方法 ✅ |
| 多步逻辑 + 清晰命名 | 显式方法 ✅ |
| 一行处理逻辑 | Lambda ✅ |
| 需要捕获外部变量 | 匿名或 lambda ✅ |
| 作为临时回调传递 | Lambda ✅ |
🔗 延伸阅读
- 📘 Microsoft 官方文档 – 匿名方法
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/anonymous-methods - 📘 Lambda 与匿名方法关系(StackOverflow)
https://stackoverflow.com/questions/317770/anonymous-method-vs-lambda-expression
下篇文章继续拓展如下内容:
- ✅ 匿名方法 + 委托链组合
- ✅ 匿名方法实现策略模式、状态模式
- ✅ 匿名方法在多线程/并发场景下的安全性分析
- ✅ 编译器如何生成匿名方法类(IL 分析)