什么是委托?
打个比方,你外卖到了你不想动,叫你室友帮你去拿,然后你室友就帮你拿了。这就是委托,委托别人帮你做一件事情。
C#中的委托:
定义:delegate
语法: 权限修饰符 delegate 返回值 委托名 (参数类型 参数);
特别注意:被委托的方法有无返回值、返回值类型、有无参数、参数类型要与委托一致
实例:
class Program
{
//创建一个委托,不带参
delegate void myDelegate1();
//创建一个委托,带参带返回值
delegate int myDelegate2(int num);
static void Main(string[] args)
{
//实例化委托
myDelegate1 d1 = new myDelegate1(one);
myDelegate2 d2 = new myDelegate2(two);
//或
//myDelegate1 d1 = one;
//myDelegate2 d2 = two;
//执行委托对象
d1();
int num = d2(123);
Console.WriteLine("num = "+num);
Console.ReadKey();
}
static void one() {
Console.WriteLine("one方法");
}
static int two(int a) {
Console.WriteLine("two方法");
return a;
}
}
委托中的多播
多播说白了,你把实例好的委托看成是一个队列或集合,+=看成是执行Add方法,-=看成是执行Remove方法,但如果你直接用 = 号那就相当于把这个方法直接赋值给了委托对象,会造成前面的添加进委托对象的方法被覆盖。
例子:
class Program
{
//创建一个委托,带参带返回值
delegate int myDelegate2(int num);
static void Main(string[] args)
{
//实例化委托
myDelegate2 d2 = two;
d2 += three;
d2 += four;
d2 += five;
d2 -= four;
//执行委托对象
int num = d2(123);
Console.ReadKey();
}
static void one() {
Console.WriteLine("one方法");
}
static int two(int a) {
Console.WriteLine("two方法");
return a;
}
static int three(int a)
{
Console.WriteLine("three方法");
return a;
}
static int four(int a)
{
Console.WriteLine("four方法");
return a;
}
static int five(int a)
{
Console.WriteLine("five方法");
return a;
}
}
什么是事件?
在代码里边,事件代表一类事情或者一个方法,一旦被触发就会执行,事件与触发器是一个整体。
C#中的事件:
定义:event
语法:权限修饰符 event 委托类 事件名;
例子:(例子中的发布器与订阅器可看为事件源与执行类)
namespace test_Delegate_Event
{
//创建一个委托
public delegate void myDelegate();
class Program
{
//触发事件
static void Main(string[] args)
{
//实例化发布器
Program2 p2 = new Program2();
//实例化订阅器
Program3 p3 = new Program3(p2);
//执行发布器中的one方法
p2.one();
Console.ReadKey();
}
}
//发布器
class Program2
{
//创建一个事件,相当于实例化委托
public event myDelegate myEvent;
public void one() {
Console.WriteLine("发布器中的one方法");
//执行触发器
if (myEvent!=null) {
myEvent();
}
}
}
//订阅器
class Program3
{
//监视发布器类
Program2 p2;
public Program3(Program2 p2) {
this.p2 = p2;
//向整个事件中添加要触发的方法
p2.myEvent += three;
}
public void two() {
Console.WriteLine("订阅器中的two方法");
}
}
}
如果你仔细看了程序的执行流程或者你可以在main方法上打上断点查看程序执行流程,你会发现:对于A类和B类,A类发布,B类订阅。就像是将B类的方法委托给A类执行(myEvent()),event更像是一个队列或集合,用来存放B类的方法(要被触发的方法)
为什么C#中的事务的定义要用到委托?
在官方文档的介绍中有这么一段描述:事件是一种特殊的多播委托。
那也就是说事件其实是委托的一种封装,事件的底层是委托。那好,为了证明这一点我们只用委托去实现整个事件与触发。
代码:
class Program
{
//触发事件
static void Main(string[] args)
{
Program2 p2 = new Program2();
//实例化订阅器
Program3 p3 = new Program3(p2);
//执行发布器中的某个方法
p2.one();
Console.ReadKey();
}
}
//发布器
class Program2
{
public delegate void myDelegate();
public myDelegate md = null;
public void one() {
Console.WriteLine("发布器中的one方法");
//执行委托
md();
}
}
//订阅器
class Program3
{
public Program3(Program2 p2) {
p2.md = two;
}
public void two() {
Console.WriteLine("订阅器中的two方法");
}
}
如果你刚入C#的坑你没必要追究C#的设计者为什么要这样设计。你若很想了解,那就是为了解耦,减少代码量,提高代码效率,提高代码合理性。
事件的多播:
既然事件是一类特殊的多播委托,那么用法肯定雷同,不同的是事件不能用 = 。
namespace test_Delegate_Event
{
public delegate void myDelegate();
class Program
{
static void Main(string[] args)
{
Program2 p2 = new Program2();
Program3 p3 = new Program3(p2);
p2.one();
Console.ReadKey();
}
}
//发布器
class Program2
{
public event myDelegate myEvent;
public void one() {
Console.WriteLine("发布器中的one方法");
myEvent();
}
}
//订阅器
class Program3
{
private Program2 p2;
public Program3(Program2 p2) {
this.p2 = p2;
p2.myEvent += two;
p2.myEvent += three;
p2.myEvent += four;
}
public void two() {
Console.WriteLine("订阅器中的two方法");
}
public void three() {
Console.WriteLine("订阅器中的three方法");
}
public void four()
{
Console.WriteLine("订阅器中的four方法");
}
}
}