不知道很多人在写东西给大家分享的时候是自己也不清楚,又或者是不愿意让大家明白,做事云里雾里的绕来绕去。反正我经常看到不准确、看不明白的学习资料、博客、答案等。
后来我总结了下【缺少应用场景】。
下面今天我给大家说说我理解和平时用到的委托、 事件,童鞋们看完觉得有帮助的来个评论。
首先咱们看一下委托怎么声明:
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表达式】。