委托和事件
Contents
委托和事件
委托是什么
- 委托 函数(方法)的容器
- 用来 存储、传递函数(方法)
- 委托的本质是一个类 用来定义函数(方法)的类型(返回值和参数的类型)
- 不同的 函数(方法)必须对应各自"格式"一致的委托
- 委托常用于类的成员或作为函数的参数使用
- 委托变量可以存储多个函数
委托基本语法
- 关键字:delegate
- 语法:访问修饰符 delegate 返回值 委托名(参数列表);
- 可以声明在namespace中或class中 一般写在namespace中
- 委托的访问修饰符 默认为public
- 不可以有同名委托(不存在重载这个概念)
定义自定义委托
无参无返回值
//声明一个 可以用来存储无参无返回值函数的容器
public delegate void MyFun();
//使用委托
MyFun f1 = new MyFun();
//另一种写法
//My Fun f1 = ()=>{Console.WirteLin("我没有参数和返回值")};
f1 += ()=>{Console.WirteLin("我没有参数和返回值")};
//委托的调用
f1();//方法1
f1.Invoke();//方法2有参数 有返回值
//声明一个 可以用来存储无参无返回值函数的容器
public delegate int MyFun(int value);
//使用委托
MyFun f2 = new MyFun((value)=>{return value+1});
int a = f2(3);
Console.WriteLine(a);//4委托可以使用复合运算符
public void Fun(){
Console.WriteLine("吃肉");
}
f2 += Fun; //吃肉
f2 = f2+Fun;//吃肉 吃肉
//从容器中移除函数
f2 = f2-Fun;//吃肉系统提供的委托
//泛型委托 可以指定返回值
Func<int> func = new Func<int>();
//无参无返回值的委托
Action action = new Action();
//可以传n个参数的 无返回值委托
Action<int,string> action2 = new Action<int,string>();
action2 += (a,b)=>{Console.WriteLine(a+b)};
//可以传n个参数 并且有返回值的
//第一个是参数 后面的是返回值
//int返回值 有两个string参数
Func<int,string,string> fun3;事件
- 事件是基于委托的存在
- 事件是基于委托的安全包裹 让委托的使用更具安全性
- 事件是一种特殊的变量类型
事件的语法
- 事件使用event关键字声明
- 事件的声明:访问修饰符 event 委托类型 事件名;
- 事件是作为 成员变量存在于类中
- 委托怎么使用 事件就怎么使用
- 委托和事件的不同点
- 不能再类外部去赋值
- 不能再类外部去调用
- 注意:它只能作为成员存在于类、接口以及结构体中
- 不可以声明在namespace中 也不可以声明在方法体中
class Test{
//委托声明
public Action MyFunc;
//事件声明
public event Action MyEvent;
Test(){
//事件可以在类内部赋值
MyEvent = new Action();
}
public void DoEvent(){
if(MyEvent == null) return;
MyEvent();
}
}
class Test2{
public void Test(){
Console.WriteLine("测试");
}
static void Main(){
Test t1 = new Test();
Test2 t2 = new Test2();
//委托可以直接赋值
t1.MyFunc = t2.test;
//事件不可以直接赋值
t1.MyEvent = t2.Test;//报错
t1.Myevent = null;//报错
//事件可以 使用复合运算符 去增加移除函数
t1.Myevent += t2.Test;
t1.Myevent -= t2.Test;
//委托可以在外部调用
t1.myFunc();
//事件不可以在外部调用
t2.myEvent();//报错
//想要在外部调用 只可以在类的内部封装 然后再外部调用
t2.DoEvent();
//委托可以生命在函数中
Aciton a = new Action();
//事件不可以
event Action a2 = new Action();//报错
}
}为什么有事件
- 防止外部随意置空委托
- 防止外部随意调用委托
- 事件相当于对委托进行了一个封装 使其更加安全
匿名函数
- 没有名字的函数
- 匿名函数主要是配合委托和事件使用
- 脱离委托和事件 是不会使用匿名函数的
- 缺点:添加到委托或者事件容器后 不记录 无法被单独移除
基本语法
Action a = delegate(参数){
//函数逻辑
};
//有返回值的
Action<string> a1 = delegate(){
retrun "阿拉拉";
}Unity自带委托
UnityAction action;
action = ()=>{};
//带参数的委托
UnityAction<string> action;