CS4L12——委托
CS4L12——委托
本章代码关键字
1 | delegate //委托声明关键字 |
委托
委托是函数(方法)的容器,可以理解为表示特定格式(参数列表和返回值类型一致)的函数(方法)的变量类型,用来存储传递函数(方法)
委托的本质是一个类,用来定义函数(方法)的类型(返回值和参数的类型),
不同的函数(方法)必须对应和各自 “格式“ 一致(即参数列表和返回值类型必须一致)的委托
简单理解 委托 就是装载、传递函数的容器而已,可以使用委托变量来 存储函数 或者 传递函数
系统已经提供了很多委托给我们用:
-
Action
:没有返回值,参数提供了 0-16 个委托给我们用 -
Func
: 有返回值,参数提供了 0-16 个委托给我们用
委托可以让我们接收外部传入的函数,然后一并执行,这在UI系统中的为按钮等控件定义触发的行为时将非常有用
基本语法
关键字:delegate
语法:访问修饰符 delegete 返回值 委托名(参数列表);
写在哪里:
可以申明在 namespace
和 class
语句块中
更多的写在 namespace
中
委托语法简单记忆就是:函数申明语法前面加一个 delegate
关键字
定义自定义委托
委托的 访问修饰符 一般不写,默认是 public
,即委托在别的命名空间中也能使用
使用 private
会让其他命名空间不能使用了,因此一般用 public
委托声明不能同名(在同一语句块中)
声明委托只是申明了规则(参数列表和返回值类型),并没有使用
委托可以使用泛型,可以让返回值和参数类型可变 方便我们的使用
1 | public delegate void MyFun(); //委托规则的申明 是不能同名的(在同一语句块中) |
调用委托以执行委托存储的函数
委托是专门用来装载 函数 的容器,可以 new
委托来声明一个空委托,或者 new
委托时传入一个函数,也可以直接赋值一个函数
要执行委托存储的函数,可以对委托调用 Invoke()
方法,也可以如方法那样直接 委托变量()
函数不能装在不匹配格式的委托里,例如有参函数就不能存储在无参委托内
注意:向委托装载一个函数时,函数不能加括号,如果加上括号就是调用该函数了
1 | public delegate void MyFun(); |
输出:
1 | 1 |
使用定义好的委托
委托类型变量是函数的容器,常用在:
- 作为类的成员
- 作为函数的参数
1 | public delegate void MyFun(); //委托规则的申明 是不能同名的(在同一语句块中) |
输出:
1 | 我做了什么 |
委托变量可以存储多个函数(多播委托)
所谓多播委托,即 “多路广播委托”(MulticastDelegate)。
从它的名字就可以看出,此种委托可以像广播一样将影响信息“传播”到四面八方。
多播委托类拥有一个方法调用列表,调用委托时,它就会逐一调用该列表中的方法,从而实现多重影响。
简单来说就是,委托可以存储多个函数,调用委托时,会依次执行存储的所有函数
可以使用 +=
向委托添加多个函数,
但是要注意,没有初始化的委托是不能直接加函数的!!! ,也就是说,不能刚声明一个委托变量时就使用 +=
MyFun ff = null
可以算是初始化,可以在后续语句里用 +=
当委托有多个函数时,会按照添加的先后顺序依次执行添加的内容
1 | public delegate void MyFun(); |
输出:
1 | 我做了什么 |
使用 -=
可以从容器中移除指定的函数,如果容器本来就没有这个函数,再去移除该函数会不进行处理
1 | public delegate void MyFun(); |
输出:
1 | 我做了什么 |
对委托直接赋值 null
即可清空委托
注意!如果委托是
null
,直接调用会报错!!!,建议用if
判断来确保不会报错
1 | public delegate void MyFun(); |
输出:
1 | ff没有存储方法 |
如果一个委托要判断确认不为 null
后才执行,除了使用 if
判断,
还可以使用 ?.Invoke()
的方法来调用委托,委托在不等于 null
时才会调用
这个 ?.
是 null
检查运算符,它用于简化判空逻辑,会在(#TODO#)内详细讲解
1 | public delegate void MyFun(); |
我们可以封装方法来为类内部的委托变量添加函数或移除函数
在类里为已经有的委托成员变量,在函数里直接使用 +=
是可以的,因为实例化类时已经默认进行了初始化(赋值为 null
)
1 | public delegate void MyFun(); |
输出:
1 | 我做了什么 |
系统定义好的委托
可以直接使用系统提供的常用委托,需要 using System
-
Action<>
是代表无返回值委托,系统提供了1-16个参数的Action
委托,直接用即可,类型可以分别指定1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22static void Main(string[] args)
{
//Action代表无返回值委托
Action action = Fun;
action += Fun3;
action();
//Action 代表无返回值委托 系统提供了1-16个参数的Action委托,直接用即可,类型可以分别指定
Action<int, String> action2 = Fun6;
}
static void Fun()
{
Console.WriteLine("我做了什么");
}
static void Fun3()
{
Console.WriteLine("你做了什么");
}
static void Fun6(int i, string s) { }输出:
1
2我做了什么
你做了什么 -
Func<>
是代表有返回值委托,系统提供了1-16个参数的Func
委托,直接用即可注意!指定类型时,参数的类型写在前面,泛型参数的最后一个一定是返回值的类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25static void Main(string[] args)
{
//Func代表可以指定返回值委托
Func<string> funcString = Fun4;
Func<int> funcInt = Fun5;
//Func 代表可以指定返回值的委托 系统提供了1-16个参数的Func委托,直接用即可
//注意!指定类型时,参数的类型写在前面,最后一个一定是返回值的类型
Func<int, int> func2 = Fun2;
}
static int Fun2(int value)
{
return value;
}
static string Fun4()
{
return "";
}
static int Fun5()
{
return 0;
}