C# 匿名方法拓展内容
                           
天天向上
发布: 2025-04-20 19:17:17

原创
713 人浏览过

接上篇文章,本篇我们继续进阶补充 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. 匿名方法在多线程 / 并发环境下使用

匿名方法配合 ThreadTask,非常适合封装局部业务逻辑

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/命名方法更佳

📚 官方参考


更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *