C# 中的delegate
(委托)是一种类型安全的函数指针,它安全地封装了方法的签名和引用。
可以将delegate
视为一种可引用的方法类型,类似于C或C++中的函数指针,但比函数指针更安全、更类型安全。
delegate
主要用于事件处理、回调方法和异步编程等场景。
委托是一种可以把引用存储为函数的类型。
委托可以引用实例和静态方法,而函数指针只能引用静态方法。
委托的声明非常类似于函数,和函数不同的的是委托不带函数体,并且需要Delegate关键字。
System.Delegate 和“delegate”关键字 - C# | Microsoft Learn
定义委托
例如,声明一个接受两个整数并返回它们之和的委托:
public delegate int CalculatorDelegate(int num1, int num2);
实例化委托
定义好委托后,可以创建该委托类型的实例,并将其绑定到符合其签名的方法上:
CalculatorDelegate calculate = AddNumbers; // 假设有一个匹配签名的方法AddNumbers// 定义匹配签名的方法
private int AddNumbers(int num1, int num2)
{return num1 + num2;
}
调用委托
一旦委托被赋值给一个方法,就可以像调用普通方法一样调用它:
int result = calculate(5, 7); // 这会执行AddNumbers方法并返回结果
使用Lambda表达式
从C# 3.0开始,你还可以使用Lambda表达式来创建delegate
的实例,这使得代码更加简洁。
calculate = (x, y) => x + y;
result = calculate (5, 3); // result is 8 calculate = (x, y) => x - y;
result = calculate (5, 3); // result is 2
多播委托(组合多个方法)
委托还可以指向多个方法,当调用时,所有关联的方法都会按照添加顺序依次执行:
CalculatorDelegate combined = AddNumbers;
combined += SubtractNumbers;// 调用会先执行AddNumbers,再执行SubtractNumbers
int finalResult = combined(10, 3);
泛型委托
C#中预定义了几个常用的泛型委托,如Action
, Func
和 Predicate
,简化了常见场景下的委托使用。
Action<T>
:用于表示没有返回值并且带任意数量输入参数的方法。Func<TResult>
:用于表示具有返回值和任意数量输入参数的方法。Predicate<T>
:用于表示返回布尔值且仅有一个输入参数的方法。
在事件中使用Delegate
delegate
在事件处理中特别有用。你可以定义一个delegate
类型来表示事件处理程序,然后在类中声明一个该类型的事件。当事件发生时,所有订阅了该事件的处理程序都会被调用。
事件(Event)与委托的关系
在C#中,事件是基于委托的实现,用于发布/订阅模型。类通常通过定义一个委托类型来声明事件,然后其他对象可以“订阅”这个事件,即添加处理方法到事件的委托引用列表中。
public event CalculatorDelegate CalculationPerformed;protected virtual void OnCalculationPerformed(int result)
{CalculationPerformed?.Invoke(result, EventArgs.Empty); // 触发事件
}
异步编程中的委托
在异步编程中,委托还常用于BeginInvoke/EndInvoke模式或Task类的ContinueWith等方法,以实现非阻塞的异步操作。
以上就是C#中委托的基本使用方式,实际应用中,委托是构建事件驱动程序、回调机制以及实现灵活方法调用的核心工具之一。