委托(二) 委托与 "回调和回调函数"

回调与回调函数

我也不太清楚为什么会出来一个 "回调函数" 的概念, 回调函数不就是一个参数吗?

将方法 A 作为 方法 B 的一个参数传入到方法 B 中, 那么方法 A 就是方法 B 的回调函数.

可以这样理解:

  1. "回调" 是一种技术: 将方法作为参数传入另一个方法! 在各大编程语言, 脚本语言中都有实现这门技术!

  2. "回调函数" 就是作为参数的方法!

强调: 回调是一项技术! 回调函数是一个参数!

"回调" 的用途

  1. 因为 A 是作为参数传入 B 的, 那么在 B 中就可以编写很多的判断逻辑来准确控制 A 的执行时机, 当然用 retuan 返回执行标志, 通过执行标志来控制 A 的执行也是可以的, 但是这样不是还得对执行标志进行一次判断吗? 当然这个没什么影响, 但是万一这个执行标志无法返回呢, 对吧?

  2. 如果 B 中需要处理很复杂的数据, 而且这个数据很难使用 return 返回, 甚至可能根本无法使用 return, 但是 A 又必须要用到这个数据, 此时就可以利用 "回调" 这项技术了, 将 A 传入 B, 在 B 的内部执行 A, 这样 A 就可以获取到需要的数据了.

  3. 假设方法 B 可以随机获得一种食材, 食材有多种多样烹饪方法, 可以红烧, 可以清蒸, 可以煎炸, 此时就可以给 B 添加一个 "回调函数" 参数, 这个参数就是烹饪方法 A, 那么在执行方法 B 获取食材的同时就可以将烹饪方法 A 一并传入, 这样一道菜就直接做好了! 而且只要传入不同的 A 就可以做出不同的菜, 甚至在 B 里面还可以写判断方法, 控制某些食材只能用某些特定的烹饪方法!

总结: "回调" 可以做菜~!

示例

csharp 中由于方法无法作为参数进行传递, 所以想要在 csharp 中实现 "回调" 需要使用委托来实现, 下面是一个简单的示例.

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;

namespace namespace_CallBackTest
{
class CallBackTest
{
// 随机器
public readonly Random random = new Random();

public static void Main()
{
CallBackTest callBackTest = new CallBackTest();

// 获取食材的同时将烹饪方法作为参数传入, 实现内部调用 -- 这就是 "回调" !
// 含义为: 先获取食材, 之后使用参数内的烹饪方式对食材进行处理, 得到烹饪后的食物.
callBackTest.GetIngredients(callBackTest.Cook1);//烧烤
callBackTest.GetIngredients(callBackTest.Cook1);//烧烤
callBackTest.GetIngredients(callBackTest.Cook2);//清蒸
callBackTest.GetIngredients(callBackTest.Cook1);//烧烤
callBackTest.GetIngredients(callBackTest.Cook3);//煎炸
callBackTest.GetIngredients(callBackTest.Cook1);//烧烤

Console.ReadKey();
}

/// <summary>
/// 获取食材
/// </summary>
/// <param name="cook">烹饪方法</param>
public void GetIngredients(Action<string> cook)
{
string str_ingredient = string.Empty;
int int_ingredient = random.Next(1, 100);

if (int_ingredient > 75)
{
str_ingredient = "大棒肉(" + int_ingredient + ")";
}
else if(int_ingredient > 25)
{
str_ingredient = "鲈鱼(" + int_ingredient + ")";
}
else if (int_ingredient == 25)
{
str_ingredient = "杂烩兔肉块(" + int_ingredient + ")";
}

if (string.IsNullOrEmpty(str_ingredient))
{
Console.WriteLine("白忙了一天, 没有获得任何食材(" + int_ingredient + ") !");
}
else
{
cook(str_ingredient);
}
}

/// <summary>
/// 烧烤
/// </summary>
/// <param name="ingredient"></param>
public void Cook1(string ingredient)
{
Console.WriteLine("获得了 <烧烤" + ingredient + "> !");
}

/// <summary>
/// 清蒸
/// </summary>
/// <param name="ingredient"></param>
public void Cook2(string ingredient)
{
Console.WriteLine("获得了 <清蒸" + ingredient + "> !");
}

/// <summary>
/// 煎炸
/// </summary>
/// <param name="ingredient"></param>
public void Cook3(string ingredient)
{
Console.WriteLine("获得了 <炸" + ingredient + "> !");
}
}
}

参考链接

  • 回调函数(callback)是什么?

  • js的回调函数一般都用来做什么