委托的概念
委托是一种引用类型,用于封装具有特定参数列表和返回类型的方法。它类似于函数指针,但提供了更高的安全性和灵活性。委托允许将方法作为参数传递、存储在变量中或从其他方法返回。
委托的声明与使用
委托的声明需要指定方法的签名(参数和返回类型)。例如:
delegate int MathOperation(int a, int b);声明后,可以将任何匹配签名的方法赋值给委托实例:
int Add(int x, int y) => x + y; MathOperation operation = Add; int result = operation(3, 5); // 调用委托,结果为8多播委托
委托支持多播,即一个委托实例可以绑定多个方法,调用时会按顺序执行所有方法。通过+=和-=运算符添加或移除方法:
void LogStart() => Console.WriteLine("开始计算"); void LogEnd() => Console.WriteLine("计算结束"); MathOperation operation = Add; operation += (a, b) => { LogStart(); return a * b; }; operation += (a, b) => { LogEnd(); return 0; };注意:多播委托的返回值通常是最后绑定的方法的返回值。
内置委托类型
.NET 提供了常用的内置委托类型,无需自定义:
Action:无返回值的方法(支持最多16个参数)。Func:有返回值的方法(最后一个泛型参数为返回类型)。Predicate<T>:返回布尔值的单参数方法。
示例:
Func<int, int, int> func = Add; Action<string> log = message => Console.WriteLine(message);委托的应用场景
- 事件处理:委托是事件的基础,用于实现发布-订阅模式。
- 回调机制:将方法作为参数传递给异步操作或耗时任务。
- 策略模式:通过委托动态切换算法或行为。
匿名方法与Lambda表达式
C# 允许使用匿名方法或Lambda简化委托的声明:
MathOperation operation = delegate(int a, int b) { return a - b; }; // 或使用Lambda MathOperation operation = (a, b) => a / b;注意事项
- 委托实例不可变,
+=和-=会返回新实例。 - 避免长时间持有委托引用,可能导致内存泄漏(如事件未注销)。
- 多播委托的执行顺序与绑定顺序一致,但依赖此特性时需谨慎设计。
通过合理使用委托,可以提升代码的模块化和扩展性,尤其在需要动态行为或解耦的场景中。