前言

C# 中的委托(Delegate)是一种特殊的类型,它安全地封装了方法的签名和引用。委托特别用于实现事件和回调方法。使用委托,可以将方法作为参数传递或赋值给变量,并可以调用委托所引用的方法。

委托的定义

委托的定义类似于方法的定义,但不带方法体。它定义了可以引用的方法的签名。

1
public delegate int MyDelegate(int x, int y);

上面的代码定义了一个名为 MyDelegate 的委托,它接受两个 int 参数并返回一个 int

委托的使用

委托的使用通常涉及三个步骤:

  1. 定义委托:如上所述。
  2. 创建委托实例:使用与委托签名匹配的方法创建委托实例。
  3. 调用委托:通过委托实例调用方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class HelloWorld
{
// 定义委托
public delegate int MyDelegate(int x, int y);

// 静态方法,与委托签名匹配
public static int Add(int a, int b)
{
return a + b;
}

public static void Main()
{
// 创建委托实例,引用 Add 方法
MyDelegate delegate = new MyDelegate(Add);

// 调用委托,实际调用的是 Add 方法
int result = delegate(5, 3);
Console.WriteLine(result); // 输出 8
}
}

委托与事件

在 C# 中,事件(Event)是基于委托的。事件提供了一种发布/订阅模型,允许类或者对象通知其他类或者对象当某些特殊事情发生时(例如,用户点击按钮)。事件的实现通常包括一个私有的委托字段和一个公共的事件成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class MyClass
{
// 定义委托
public delegate void MyEventHandler(object sender, EventArgs e);

// 声明事件
public event MyEventHandler MyEvent;

// 触发事件的方法
protected virtual void OnMyEvent(EventArgs e)
{
MyEventHandler handler = MyEvent;
if (handler != null)
{
handler(this, e);
}
}

// 其他方法,在适当的时候调用 OnMyEvent
}

// 订阅事件的类
public class MySubscriber
{
public void HandleMyEvent(object sender, EventArgs e)
{
Console.WriteLine("MyEvent was raised!");
}
}

// 使用示例
public class HelloWorld
{
public static void Main()
{
MyClass myObject = new MyClass();
MySubscriber subscriber = new MySubscriber();

// 订阅事件
myObject.MyEvent += subscriber.HandleMyEvent;

// 假设在某个地方触发了事件
myObject.OnMyEvent(EventArgs.Empty); // 输出 "MyEvent was raised!"
}
}

委托的链式调用

委托可以使用 += 运算符进行链式调用,这意味着可以将多个方法关联到同一个委托实例,当调用委托时,所有关联的方法都会按照它们被添加的顺序依次执行。同样地,可以使用 -= 运算符来移除之前添加的方法。

泛型委托

C# 还支持泛型委托,如 Func<TResult>Action<T> 系列,它们分别用于表示有返回值和无返回值的方法。

1
2
3
4
5
Func<int, int, int> add = (a, b) => a + b;
int sum = add(5, 3); // sum 现在是 8

Action<string> display = (message) => Console.WriteLine(message);
display("Hello, World!"); // 输出 "Hello, World!"

C#委托真的非常强大!!!

相关链接:

[1] C#中的委托和事件