来一步一步地理解 C# 中的委托(Delegate),包括它的:

  • 作用
  • 为什么要用它
  • 📌什么时候用它
  • 💡多个通俗易懂的例子

一、什么是委托?(通俗理解)

你可以把 委托 想象成:

“一个方法的电话号码本。”

比如你有个朋友叫小明,你要找他办事,你就得先知道他的电话号码。
在程序中,委托就是这个“电话号码”,用来告诉程序:“等一下我要调用哪个方法。”


二、委托的作用是什么?

委托的主要作用是:

✅ 1. 把方法作为参数传递

就像你把整数、字符串传给一个函数一样,委托允许你把方法本身当作参数传进去。

✅ 2. 实现回调机制

当某个任务完成后,自动通知另一个方法去处理后续逻辑。

✅ 3. 支持事件模型

事件(Event)底层就是基于委托实现的。


三、为什么要使用委托?

场景 原始做法 使用委托的好处
调用不同方法 写很多 if/else 判断 直接赋值不同的方法到委托变量,灵活切换
异步操作完成通知 主线程不断检查状态 异步执行完后自动调用回调方法
事件处理 手动写一堆判断 系统帮你管理谁响应哪个事件

四、什么时候使用委托?

使用场景 说明
🔁 回调函数 当一个方法执行完毕后,要调用另一个方法做后续处理
🧩 插件式编程 让别人传入自己的方法来定制行为
📣 事件订阅 如按钮点击、数据更新时通知其他模块
🔄 多态替代 不需要继承,也能实现类似多态效果
⏱ 异步编程 任务完成后触发指定的方法

五、举几个通俗易懂的例子


✅ 示例1:最简单的委托使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;

// 定义一个委托,表示无参数、返回 void 的方法
public delegate void MyDelegate();

class Program
{
static void Main()
{
// 创建委托实例,指向 Greet 方法
MyDelegate del = new MyDelegate(Greet);

// 调用委托
del(); // 输出:你好!
}

static void Greet()
{
Console.WriteLine("你好!");
}
}

📌 解释

  • 我们定义了一个“打招呼”的委托。
  • Greet 是具体的方法。
  • del() 就像打电话说:“该打招呼了”。

✅ 示例2:带参数的委托

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;

// 表示接收一个 string 参数、无返回值的方法
public delegate void MyDelegate(string name);

class Program
{
static void Main()
{
MyDelegate del = SayHello;
del("张三"); // 输出:你好,张三!
}

static void SayHello(string name)
{
Console.WriteLine("你好," + name + "!");
}
}

📌 解释

  • 这个委托能接收一个名字,然后打印问候语。
  • 可以换方法,也可以换参数,非常灵活。

✅ 示例3:使用 Action 替代自定义委托(推荐写法)

1
2
3
4
5
6
7
8
9
10
11
using System;

class Program
{
static void Main()
{
// 使用内置委托 Action<string>
Action<string> say = msg => Console.WriteLine(msg);
say("Hello, 委托简化写法!");
}
}

📌 解释

  • Action<string> 是系统已经定义好的委托类型。
  • 这里直接用了 Lambda 表达式,更简洁。

✅ 示例4:委托实现回调机制

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
using System;
using System.Threading;

class Program
{
// 定义一个回调委托
public delegate void Callback();

static void Main()
{
DoWork(OnWorkCompleted); // 传入回调方法
}

static void DoWork(Callback callback)
{
Console.WriteLine("开始工作...");
Thread.Sleep(2000); // 模拟耗时操作
Console.WriteLine("工作完成");

callback(); // 调用回调
}

static void OnWorkCompleted()
{
Console.WriteLine("任务已完成,请继续下一步");
}
}

📌 输出结果

1
2
3
开始工作...
工作完成
任务已完成,请继续下一步

📌 解释

  • DoWork 是一个耗时任务。
  • 它完成后自动调用 OnWorkCompleted 方法通知主线程。
  • callback(); // 调用回调 我理解的意思就是 :提前说好做完这件事后通知我

✅ 示例5:委托实现策略模式(动态切换行为)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;

delegate int Operation(int a, int b);

class Program
{
static void Main()
{
Operation op;

// 根据条件选择不同操作
op = Add; // 或者 op = Subtract;

Console.WriteLine("结果:" + op(10, 5)); // 输出:15
}

static int Add(int a, int b) => a + b;
static int Subtract(int a, int b) => a - b;
}

📌 解释

  • 通过改变 op 的指向,我们可以动态切换加法或减法。
  • 类似于“策略模式”,非常灵活。

六、总结一句话:

委托就像是“方法的变量”,它可以:

  • 存储方法;
  • 作为参数传递;
  • 动态调用;
  • 实现回调和事件;
  • 极大地提升代码灵活性。