C# 匿名方法拓展内容
接上篇文章,本篇我们继续进阶补充 C# 匿名方法的使用,涉及委托链、多线程、设计模式、IL 编译原理等专业内容,帮你彻底掌握这门技术 。
1. 匿名方法 + 委托链组合(Multicast Delegate)
匿名方法可以被添加到委托链中,实现多事件监听 / 多任务处理。
示例:多个处理器响应一个事件
public delegate void LogHandler(string message);
class Program
{
static void Main()
{
LogHandler logger = delegate (string msg) {
Console.WriteLine($"控制台日志:{msg}");
};
logger += delegate (string msg) {
System.IO.File.AppendAllText("log.txt", msg + "\n");
};
logger("应用程序启动");
}
}
2. 匿名方法 + 策略模式(Strategy)
匿名方法可作为策略传入,替代传统的命名策略类。
示例:
public class PriceCalculator
{
public double Calculate(double price, Func<double, double> discountStrategy)
{
return discountStrategy(price);
}
}
class Program
{
static void Main()
{
var calculator = new PriceCalculator();
double result = calculator.Calculate(100, delegate (double p) {
return p * 0.9; // 10% off
});
Console.WriteLine($"折扣后价格:{result}");
}
}
3. 匿名方法在多线程 / 并发环境下使用
匿名方法配合 Thread 或 Task,非常适合封装局部业务逻辑。
using System.Threading;
Thread thread = new Thread(delegate ()
{
Console.WriteLine($"子线程执行中,线程ID={Thread.CurrentThread.ManagedThreadId}");
});
thread.Start();
✅ 注意闭包陷阱:匿名方法访问的变量是引用,不是拷贝。
for (int i = 0; i < 3; i++)
{
Thread t = new Thread(delegate () {
Console.WriteLine(i); // 输出可能是 3,3,3(不是 0,1,2)
});
t.Start();
}
解决方法是捕获临时变量:
for (int i = 0; i < 3; i++)
{
int temp = i;
Thread t = new Thread(delegate () {
Console.WriteLine(temp); // 正确输出 0,1,2
});
t.Start();
}
4. 匿名方法用于事件监听与解绑
你不能直接 -= 匿名方法,除非保存引用:
EventHandler handler = delegate { Console.WriteLine("点击"); };
button.Click += handler;
button.Click -= handler; // ✅ 有引用才能解除绑定
5. IL 分析:匿名方法是如何被编译的?
C# 编译器将匿名方法封装成一个私有类中的方法(闭包类),变量作为字段捕获。
举个例子:
int x = 10;
Func<int> f = delegate { return x + 1; };
编译后等效为:
class Closure
{
public int x;
public int AnonymousMethod()
{
return x + 1;
}
}
你可以使用 ILSpy 或 SharpLab.io 查看编译结果。
6. 性能对比:匿名方法 vs Lambda vs 显式方法
| 项目 | 匿名方法 | Lambda 表达式 | 普通方法 |
|---|---|---|---|
| 可读性 | 一般 | ✅ 高 | ✅ 高 |
| 编译效率 | 中 | ✅ 高 | ✅ 高 |
| 性能(调用) | 基本相同 | ✅ 稍快(优化) | ✅ 稍快 |
| 闭包支持 | ✅ 支持 | ✅ 支持 | ✅ 支持 |
| 结构清晰性 | ❌(可能嵌套) | ✅ 好 | ✅ 非常好 |
📌 总结:
- 性能差别可以忽略,关键在于可读性与维护性
- Lambda 更简洁现代(推荐)
- 匿名方法适合复杂逻辑但又不需要复用
7. 实战建议
| 需求场景 | 建议用法 |
|---|---|
| 简单回调或过滤器 | ✅ Lambda 表达式 |
| 临时多行逻辑(带状态) | ✅ 匿名方法 |
| 可复用方法(多处调用) | ✅ 显式命名方法 |
| 涉及异步或泛型闭包 | ✅ Lambda/命名方法更佳 |
📚 官方参考
更多详细内容请关注其他相关文章!