委托:
什么是委托:
委托是用户自定义类型,这一点和类,接口等一样的。委托是引用类型。
委托指向一系列具有相同签名和返回类型的方法的地址。
调用委托的时候,它所包含的所有方法都会被执行。
可以理解为用来存储方法,委托就是用来存储方法的一种解决方案。
现实中:张三委托李四去做一件事。站在张三的角度,张三委托了李四,站在李四的角度,李四是张三的代理。
委托的本质:
委托其实是将一个方法作为参数传递给另一个方法。(委托可以充当方法的回调函数的类型)。
委托是方法的引用。(即委托是方法的代理)。
委托可以引用多个方法。(如:多播委托)。
可以把委托理解成一系列方法的代理,调用委托就相当于调用了一系列的方法。
委托如何定义:
使用delegate关键字定义
a.委托可以声明在类外部,也可以在类内部
b.跟方法有点类似,有参数,返回值,访问修饰符,比方法声明多一个关键字delegate
public delegate void SayHello()
创建委托的公式:
delegate 该委托存储的方法的返回值 委托的名字(该委托的方法的参数)
委托怎么使用/调用?
委托如何使用:
- 通过new来实例化
- 通过一个方法,这个是编译器提供的语法糖
- 通过一个匿名委托
- 拉姆达Lambda
实例化(让某个委托类型去代理一系列方法地址)
实例化有一种简写,只要方法满足委托的,就可以直接赋值给委托。
internal class Program
{
public delegate void SayHello();
static void Main(string[] args)
{
//实例化 (让某个委托类型去代理一系列方法地址) C#1.0写法
SayHello sayHello = new SayHello(Method1);
//调用
sayHello();
// 实例化有一种简写,只要方法满足委托的,就可以直接赋值给委托
SayHello sayHello2 = Method2;
//调用
sayHello2();
}
public static void Method1() {
Console.WriteLine("方法1");
}
public static void Method2()
{
Console.WriteLine("简写");
}
}
使用匿名委托进行实例化,匿名委托本质就是匿名方法(匿名函数:没有名称方法) C# 2.0 写法
匿名函数包括两种:1。匿名委托 2。Lambda拉姆达(表达式,语句)
public delegate bool Delegate2(string arg);
static void Main(string[] args)
{
Delegate2 delegate2 = Method3; //代理非匿名方法
//多播委托: 一个委托实例,同时代理多个方法地址。
delegate2 += Method4;
delegate2 -= Method3;
Delegate2 delegate22 = delegate (string arg) {
return arg == "hello";
};
delegate2("Method3");
delegate22("Method4-hello");
}
public static bool Method3(string arg) {
Console.WriteLine("方法3");
return arg == "hello";
}
public static bool Method4(string arg) {
Console.WriteLine("方法4");
return true;
}
}
委托如何调用:
(前两个比较常用)
a.委托实例名直接调用。
如:SayHello sayChinese = new SayHello(SayChinese);
sayChinese();
b.Inovke执行委托
如果委托定义没有参数,则Inovke也没有参数;委托没有返回值,则Inovke也没有返回值
c.BeginInvoke开启一个新线程执行委托
NetCore不支持,NetFamework支持 NetCore有更好的多线程功能来支持实现类似功能d.EndInvoke等待BeginInvoke执行完成后再执行
事件:
什么是事件:
事件是用户操作,例如按键、单击、鼠标移动等。
在C#中,事件是一种特殊的委托,事件是基于委托的,即事件是某个委托的实例(简单理解:事件是由委托创建出来的变量而异)。
两个核心:
a.事件执行的时机 b.事件执行的业务逻辑
语言中事件,指委托的实例。把委托看作一种类型,而事件就是委托的个体(实例)
定义格式:public event EventHandler clickEvent;
WinForm窗体程序看到很多的事件类型(Click,MouseXXX,KeyXXX等),事件类型其实是不同的事件变量
事件是什么?
(1)事件是委托实例,增加一个关键字Event,是特殊的委托(用委托生成的一个变量而异)
(2)事件只能在当前类被访问,子类和类外部均不能执行类中的事件方法(安全)
(3)委托和事件从本质上来说没啥区别(事件基于委托,没有委托,就没事件。)
定义事件:
定义一个事件。使用event关键字。 EventHandler委托类型 MyClick就是委托实例,即事件变量。
public static event EventHandler MyClick; // 默认值null
事件实例化(和委托实例化基本一致。只是第一初始化时,也可以使用+=或-=)
internal class Program
{
// 定义一个事件。使用event关键字。 EventHandler委托类型 MyClick就是委托实例,即事件变量。
public static event EventHandler MyClick; // 默认值null
static void Main(string[] args)
{
//定义事件?
EventHandler click1 = new EventHandler((sender, arg) => { }); // 委托实例,不是事件
//事件实例化(和委托实例化基本一致。只是第一初始化时,也可以使用 += 或 -=)
MyClick = Program_MyClick;
MyClick += Program_MyClick1;
MyClick += delegate (object sender, EventArgs arg)
{
Console.WriteLine("匿名委托");
};
MyClick += (sender, arg) =>
{
Console.WriteLine("拉姆达语句");
};
//调用事件?
MyClick.Invoke(null, null);
}
private static void Program_MyClick(object sender, EventArgs e)
{
Console.WriteLine("事件第一次赋值");
}
private static void Program_MyClick1(object sender, EventArgs e)
{
Console.WriteLine("事件第二次赋值");
}
}
事件定义的位置:
类内部,不能在方法内部
事件本质:
事件本质:指委托的实例。事件肯定是委托,但委托不一定是事件。
事件是一种特殊的委托实例。特殊在哪里?安全的委托实例。
事件主要包括三个部分:
1. 事件的订阅者(控件,比如:Button,Button对于事件来说就是一个用户)
2. 事件的触发者(各种操作,比如:点击)
3. 订阅者和触发者之间的数据传输通道(事件句柄:一头连接着订阅者,一头连接着触发者)
报社:观察者,发布者
用户:订阅者,接收者
观察者 通知 订阅者 让订阅者做去做“事”
多播:
委托是一系列方法的引用,调用委托时,可以同时执行多个方法。
多播委托,就是用一个委托代理多个方法,调用委托时,可以执行多个方法。
多播委托的本质是运算符重载 += 、 -=
多播委托好处:广播事件(多次绑定事件,或者说绑定多个事件)。为了通知。
事件和委托的区别?
参考:
- 委托是类型,而事件不是。委托可以直接赋值给一个变量,而事件则需要通过加关键字event来声明,这样才能被赋值,并且只能通过+=和-=来进行注册和注销方法的操作。
- 委托是类型安全的,而事件不是。委托是强类型的,是方法的引用,只要方法的参数和返回值能够匹配委托,就可以赋值给委托。这是事件的灵活性之处,但也是风险,因为它不是类型安全的。
- 事件基于委托,事件提供了一种安全的方式来注册和触发事件,限制了对事件的注册和触发,只能通过+=,-=和raise(触发事件)操作。