第二部分:C#进阶
第6章:委托与事件
6.1 委托的定义与使用
1. 委托的基本概念
委托(Delegate)是C#中的一种类型,它允许将方法作为参数传递或存储方法的引用。委托类似于函数指针,但它是类型安全的,并且可以引用静态方法或实例方法。
关键特性:
- 委托是类(
System.Delegate的派生类),但声明方式类似方法签名。 - 支持多播(通过
+=和-=组合多个方法调用)。 - 广泛用于事件处理、回调机制等场景。
2. 委托的声明与实例化
语法示例:
// 声明委托类型
public delegate void MyDelegate(string message);
// 实例化委托并绑定方法
MyDelegate del = new MyDelegate(PrintMessage);
// 绑定静态方法
static void PrintMessage(string msg) => Console.WriteLine(msg);
多播委托示例:
MyDelegate del1 = Method1;
MyDelegate del2 = Method2;
MyDelegate combined = del1 + del2; // 组合委托
combined("Hello"); // 依次调用Method1和Method2
3. 委托的常见用途
回调机制
将方法作为参数传递给异步操作(如文件读写完成后的通知)。public void LongRunningTask(Action callback) { // 模拟耗时操作 Thread.Sleep(1000); callback?.Invoke(); }事件驱动编程
委托是事件(event)的基础,例如按钮点击事件的触发。策略模式
通过委托动态切换算法逻辑:public delegate int Calculation(int a, int b); public int Execute(Calculation calc, int x, int y) => calc(x, y);
4. 内置委托类型
C#提供了预定义的通用委托,避免重复声明:
Action:无返回值的方法(支持最多16个参数)。Func:带返回值的方法(最后一个泛型参数为返回类型)。Predicate:返回布尔值的单参数委托。
示例:
Func<int, int, string> sumToString = (a, b) => (a + b).ToString();
Action<string> log = Console.WriteLine;
5. 委托的注意事项
- 空引用检查:调用委托前需检查是否为
null(可通过?.Invoke()简化)。 - 线程安全:多播委托的调用顺序可能与绑定顺序一致,但需注意线程同步问题。
- 性能:频繁创建的委托可能导致GC压力,可考虑缓存实例。
代码实战:委托实现排序逻辑
List<int> numbers = new List<int> { 3, 1, 4, 2 };
// 使用委托定义排序规则
Comparison<int> descending = (a, b) => b.CompareTo(a);
numbers.Sort(descending); // 结果为 [4, 3, 2, 1]
扩展阅读
委托在C# 2.0后支持协变(Covariance)和逆变(Contravariance),允许更灵活的签名匹配。
