委託 Delegate
- 委託:是一種「引用類型」變量,用於儲存某個方法的「引用地址」。
定義格式:
1
| public delegate 返回值類型 委託類型名字(參數類型1 參數名字,參數類型2 參數名字, ...)
|
只關心輸入、輸出,所以輸入、輸出就決定了一個方法的簽名
案例
1
2
3
4
5
6
7
8
9
10
11
12
13
| //聲明了一種數據類型(委託類型)叫做Calculate,代表的是某一類方法
public delegate int Calculate(int x, int y);
static int Add(int x, int y) {
return x + y;
}
static int Multiply(int x, int y) {
return x * y;
}
.....
Calculate calc1 = new Calculate(Add); //calc1存放Add方法的地址
Calculate calc2 = new Calculate(Multiply); //calc2存放Multiply方法的地址
|
調用委託方法(invoke或())
invoke調用委託方法與 ()直接調用相同
1
2
3
4
| //調用Add方法
calc1.invoke(1,2);
//調用Multiply方法
calc2(1,2)
|
代理給他=委託
calc1 是什麼意思呢?Calculate己經被聲明為一種數據類型,那麼就代表可以用它來聲明一個變量new 一個 Calculate 類型的委託對象/物件- 它裡面存放一個
Add 方法的地址 - 也就是說
calc1 變量存放一個Add方法 calc2 變量存放一個Multiply方法
練習
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
| /*
* 委託
* 概念:是一種「引用類型」的變量,儲存某一個方法的內存地址
*/
namespace Delegate
{
internal class Program
{
//聲明了一種數據類型(委託類型) 叫做Calculate,代表的是某一類方法
//輸入: int, int,輸出: int
public delegate int Calculate(int x, int y);
static void Main(string[] args)
{
//直接調用Add方法
//int sum = Add(1, 2);
Calculate calc1 = new Calculate(Add);
Calculate calc2 = new Calculate(Multiply);
int sum = calc1.Invoke(1, 2);
Console.WriteLine(sum);
int mul = calc2(1, 2);
Console.WriteLine(mul);
Console.Read();
}
public static int Add(int x, int y) {
return x + y;
}
public static int Multiply(int x, int y) {
return x * y;
}
}
}
|
委託存在的意義
- 回調方法(CallBack Method):當某個任執行完畢後,或者某事件觸發後,調用的方法。
遊戲
例如遊戲介面上有很多的 Button
- 按鈕們彼此只有外觀不同,所以肯定是同一個 Class Button 通過 new 出來的對象/物件
- 按鈕們被點擊之後,所執行的任務彼此不同,即調用了不同的響應方法
- 按鈕對象中會保存一個回調方法,當點擊後調用此回調方法
1
2
3
4
5
6
7
8
9
10
| class Button {
//聲明一種委託類型OnClickDelegate
public delegate void OnClickDelegate();
......
//用OnClickDelegate這個數據類型,聲明了一個對象/物件OnClick
public OnClickDelegate OnClick = null;
......
//如果有點擊的事件發生,就去調用OnClick這樣一個委託,讓它去執行它所包含函數
public void Click() { OnClick(); }
}
|
實作演示
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
| /*
* 委託
* 概念:是一種「引用類型」的變量,儲存某一個方法的內存地址
*/
namespace Delegate
{
//1. 場景上所有的按鈕,都是當前Button類別 實體化的物件
//2. 每個按鈕點擊後,發生的事情都不一樣
//3. 每個按鈕點擊後,發生的事情由外界決定
class Button
{
//1.聲明一個點擊消息響應的方法類型簽名(委託)
public delegate void OnClickDelegate();
//2.聲明一個OnClickDelegate類型的委託
public OnClickDelegate onclick = null;
//3.在點擊事件後,調用onClick委託儲存的方法
public void Click()
{
Console.WriteLine("按鈕被點擊了");
if (onclick != null) onclick();
}
}
internal class Program
{
static void Main(string[] args)
{
//遊戲開始
Button gameStartButton = new Button();
gameStartButton.onclick = new Button.OnClickDelegate(OnGameStart);
gameStartButton.Click();
//分享給好友
Button friendButton = new Button();
friendButton.onclick = new Button.OnClickDelegate(OnFriend);
friendButton.Click();
Console.Read();
}
//點擊了「遊戲開始按鈕」而觸發的方法
public static void OnGameStart() {
Console.WriteLine("遊戲開始");
}
public static void OnFriend() {
Console.WriteLine("分享給好友");
}
}
}
|
試驗不同角色
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
| /// <summary>
/// 控制遊戲流程的類別
/// </summary>
internal class GameController
{
public string name = "";
public GameController() { }
//遊戲開始
public void OnGameStart() {
Console.WriteLine($"{name} 遊戲開始");
}
//分享給好友
public void OnFriend() {
Console.WriteLine($"{name} 分享給好友");
}
}
//1. 場景上所有的按鈕,都是當前Button類別 實體化的物件
//2. 每個按鈕點擊後,發生的事情都不一樣
//3. 每個按鈕點擊後,發生的事情由外界決定
class Button
{
//1.聲明一個點擊消息響應的方法類型簽名(委託)
public delegate void OnClickDelegate();
//2.聲明一個OnClickDelegate類型的委託
public OnClickDelegate onclick = null;
//3.在點擊事件後,調用onClick委託儲存的方法
public void Click() {
Console.WriteLine("按鈕被點擊了");
if (onclick != null) onclick();
}
}
internal class Program
{
//聲明了一種數據類型(委託類型) 叫做Calculate,代表的是某一類方法
//輸入: int, int,輸出: int
public delegate int Calculate(int x, int y);
static void Main(string[] args)
{
GameController gameController1 = new GameController();
gameController1.name = "Rii";
GameController gameController2 = new GameController();
gameController2.name = "Rivaaa";
//遊戲開始
Button gameStartButton = new Button();
gameStartButton.onclick = new Button.OnClickDelegate(gameController1.OnGameStart);
gameStartButton.Click();
//分享給好友
Button friendButton = new Button();
friendButton.onclick = new Button.OnClickDelegate(gameController2.OnFriend);
friendButton.Click();
Console.Read();
}
}
|
委託存在的意義二次思索
1
2
3
4
5
6
7
| class StartButton {
public void OnClick() {
//開始遊戲的邏輯
Game game = new Game();
GameMap map = new GameMap();
}
}
|
Game類和GameMap類只存在於當前項目中
Button內部應該是乾淨的,無與項目其他類無關的內容!
1
2
3
4
5
6
7
8
9
| class Button {
public delegate void OnClickDelegate();
......
public OnClickDelegate onClick = null;
......
public void Click() {
if(onClick != null) onClick();
}
}
|
https://www.bilibili.com/video/BV1TP411R72r