委托和事件的总结(应用场景、扩展【匿名函数、lambda】)

时间:2021-10-17 18:58:17

  不知道很多人在写东西给大家分享的时候是自己也不清楚,又或者是不愿意让大家明白,做事云里雾里的绕来绕去。反正我经常看到不准确、看不明白的学习资料、博客、答案等。

后来我总结了下【缺少应用场景】。

  下面今天我给大家说说我理解和平时用到的委托、 事件,童鞋们看完觉得有帮助的来个评论。

首先咱们看一下委托怎么声明:

 private delegate void m_delegate(); 

这句就声明了一个委托,看不懂没关系,咱们挨个词解释:

1.private  作用域 

2、delegate 委托的关键字

3、void  返回值类型

4、m_delegate 我定义委托的名字

5、() 说明我定义的委托没有参数,如果有参数可以是这样(string str)

好了解释完委托的声明语法,看看下面比较常规的方法定义语法:

//方法1

private void function1()
{
Console.WriteLine("1");
}

//方法2
private void function2()
{
Console.WriteLine("2");
}

//方法3
private void function3()
{
Console.WriteLine("3");
}

上面我定义了3个方法,大家看看这三个方法:1)私有的、2)没有返回值、3)没有传入参数、4)名字不一样。

除了名字不一样,他们有3个共同点。

不只是这3个方法有共同特点,它们跟咱们一开始声明的委托也是很象。共同点也是:1)私有的、2)没有返回值、3)没有传入参数

好了,大家看出点什么了没有,我说一下委托我自己的定义:将长的很像的方法(作用域、返回值、传入参数相同)抽象出来,然后起一个名字,就是委托。简单点就是有共同特性方法的抽象。

那么,好像是知道了什么是委托,怎么用呢?看看下面代码的应用场景:

int aa;


private void MainFunctiuon()
{

aa=1;

//逻辑判断
switch (aa)
{
case 1:
function1();
break;
case 2:
function2();
break;
case 3:
function3();
break;
default:

break;
}
}

//调用上面的MainFunctiuon方法

private void Test()
{
MainFunctiuon();
}

执行Test()结果是执行function1方法的方法体的内容,——打印1

代码解释:我定义了一个int类型的变量aa,当然后判断aa的值来执行相应的函数,如果要是有很多种可能性咱们的代码就无限多了,怎么办呢?咱们试试委托:

//原始代码(跟上面的一致)

int aa;
private void MainFunctiuon()
{
aa = 1;
switch (aa)
{
case 1:
function1();
break;
case 2:
function2();
break;
case 3:
function3();
break;
default:

break;
}
}

//利用委托的方法
private void MainFunctiuon1(m_delegate Delegate)
{
Delegate();
}

private void Test()
{
MainFunctiuon1(function1);
}

执行Test()结果是执行function1()方法体的内容,——打印1

对比下MainFunctiuon1和MainFunctiuon这两个方法:

private void MainFunctiuon()
{
aa = 1;
switch (aa)
{
case 1:
function1();
break;
case 2:
function2();
break;
case 3:
function3();
break;
default:

break;
}
}

private void MainFunctiuon1(m_delegate Delegate)
{
Delegate();
}

哪个简洁一目了然.在上面的例子中,委托的用法就是把委托当成类型来用了(方法的类型,方法名当成了参数)。说实话这种应用场景不是太常见,最起码我见的少。

下面咱们说说第二种用法:委托,听起来字面上的意思是自己不干某件事,委托给别人干。如果一个班打扫卫生,班里50个人,49人都不干。就相当于这49个人吧打扫卫生委托给了1个人,这1个人干了49个人的事。

那么,接上面的例子,如果我一个方法想打印1和2.另一个方法想打印1和2和3,怎么办:

//打印1和2

private void Print1()
{
function1();
function2();
}

//打印1和2和3

private void Print2()
{
function1();
function2();
function3();
}

这是比较常规的写法,咱用委托来试试:

//打印1和2

private void Print4()
{
m_delegate m = new m_delegate(function1);
m += function2;
m();
}

//打印1和2和3

private void Print3()
{
m_delegate m = new m_delegate(function1);
m += function2;
m += function3;
m();
}

上面是委托的写法,因为委托是引用类型,所以要【实例化】。+=符号的意思是注册,左边是你委托的实例右边是注册的方法,不论你注册多少个方法给你的委托实例,当你执行【你的委托实例.()】的时候注册的所有方法都会执行。(起个不太恰当的词叫——方法链,一个委托相当于一串方法可不是方法链嘛。)

好了咱们总结下委托的2个应用场景:

1、当做方法的类型来用,把方法当做参数传入方法。

2、方法链:一个委托注册了多个方法,当执行这个委托实例时候,所有注册的方法一起执行。

[事件……………………………………………………………………………………………………………………………………]

为啥委托和事件经常一块被别人提起,那是因为事件是一种特殊的委托。别晕咱们看看事件为什么叫特殊的委托,先看看事件的声明语法:

public delegate void m_delegate();
public event m_delegate m_event;

看到了吧,要声明事件,先声明一个委托,然后基于这个委托在声明事件。当然这还不足以说明事件是特殊的委托,理由不够充分,看看事件的用法:

 m_event += function1;

上面的一句话,跟委托的注册方法是一样的,当事件触发的时候执行function1方法的方法体中的代码。

事件需要在方法中触发:拿winform程序的加载事件的处理函数来举例:

namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{


public delegate void m_delegate();
public event m_delegate m_event;

 

private void Form1_Load(object sender, EventArgs e)
{
if (m_event != null)
{
m_event();
}
}


}
}

其中红色代码部分的意思是:如果m_event 事件有注册的方法,那么执行这个方法。这个是事件的常用的应用场景跟委托的方法链是不是很像。。。。。。

 

下一篇咱看看委托的特殊注册方法的用法,其中会用到2个比较晦涩的词【匿名函数】、【lambda表达式】。