专栏首页静心物语313的Coding事件与委托的区别就是“+=”和“-="?

事件与委托的区别就是“+=”和“-="?

什么是事件?

事件(通过委托实现的,委托才是事件能正常执行的核心内容)

事件的作用:

事件的作用与委托变量一样,只是功能上比委托变量有更多的限制。(比如:1.只能通过+=或 -= 来绑定方法(事件处理程序)2.只能在类内部调用(触发)事件。)

事件语法:public event Mydel _mdl;

本实验步骤:(明白事件与委托的区别,先用委托来实现!)

1、添加WebForm窗体

2、自己定义一个控件(项目右键,添加,用户控件,托Button控件进来)

3、声明变量i=0;

4、点击按钮“三连击”写代码,记得i==3的时候要清0;

5、F6启动生成!

6、回到窗体Form1.拖进来userClick控件,生成项目!

总结:这样不好,方法写死,点击事件的方法写死。我想要点击这个按钮还可以用于其他的功能,,用委托实现!!!

7.改进:

8、在userClick这个类中,定义委托 MyDel...在单击事件这个方法上写上委托字段,接收方法变量。

9、写完毕,点击F6,启动生成!

10、运行,此时,发现,点击”三连击“按钮,没有了任何的反应,因为委托中的方法是空的;;

11、双击Form1进入窗体加载的事件,,对委托中进行赋值方法,调用方法(写你想要的方法)

12、写方法;

13、下面接着添加一个普通的按钮,

private void button1_Click(object sender, EventArgs e)
            {
                      userClick1._mdl();//此时,发现,使用不是很安全,因为可以被其他的点击事件直接调用
                   }

Form1代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace 三连击
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //userClick1._mdl = Show;   //窗体加载的时候。我要给这个按钮做什么。我就给它赋值一个方法名字就行了
            userClick1._mdl = Do;
        }
        public void Show()
        {
            MessageBox.Show("不错,就是这样!");
        }
        public void Do()
        {
            MessageBox.Show("人性!");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            userClick1._mdl();//此时,发现点击这个按钮一次就可以出发三连接的效果,
                              //使用不是很安全,因为可以被其他的点击事件直接调用
                                //下面用事件,就可以避免这种情况的发生1
        }
    }
}

userClick 代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace 三连击
{
    public delegate void MyDel();
    public partial class userClick : UserControl
    {
        public userClick()
        {
            InitializeComponent();
        }
        int i = 0;
        public MyDel _mdl;//定义一个委托字段
        private void button1_Click(object sender, EventArgs e)
        {
            i++;
            if (i==3)
            {
                i = 0;// 清零
                //MessageBox.Show("三连击");
                if (this._mdl!=null)
                {
                     _mdl();//委托不为空,就将委托字段_mdl,拿进来!!
                }
            }
        }
    }
}

总结:你辛苦的创建了一个委托进行事件的调用,可是,却被其他的,事件也可轻易地调用,不是想要的结果,。。可以这么说:你定义了一个报警器,当你吸烟的时候,就会警告。其他的事情发生就不会发出警告的。。可是,有一天,别人在你家外边敲了一下你的门子,你的警报器也响了。是不是感觉,这个警报器,失灵了呢。。。所以,就要对这个警报器,进行修改了!

14、下面用事件,就可以避免这种情况的发生1

事件!概念!!

新建项目 ---->>事件三连击

15、步骤和三连接是一样的,在委托字段前加上关键字event

唯一不同的是,在这里添加了 关键字 event ,就变成了事件

16、这里可以尝试着,写上DoSth()方法,发现是不行的。因为事件只能使用 ”+=“来赋值。。”-=“来移除事件,而没有 “ = ”这样的使用方法,所以这样就避免了,被赋值的现象!!!

Form 1代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 事件三连击
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
               //窗体加载的时候,给按钮注册事件!
            //userClick1._mdl = DoSth();   //假设有DoSth()这个方法
             userClick1._mdl += userClick1__mdl;        
        }
        void userClick1__mdl()
        {
            //throw new NotImplementedException();
            MessageBox.Show("+=后按下Tab键,就可以自动弹出方法了");
        }
        private void button1_Click(object sender, EventArgs e)
        {
            //userClick1._mdl(); //发现这里是不能调用的  ”=“不起作用
        }
        //public void DoSth()
        //{
        //    MessageBox.Show("这就是事件!!");
        // }
        //F6有错误!说明事件没有  =   号这个用法,只有  +=   —=这样的用法,所以就避免了,被赋值的事情的发生
    }
}

userClick 代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 事件三连击
{
    public delegate void MyDel();
    public partial class UserClick : UserControl
    {
        public UserClick()
        {
            InitializeComponent();
        }
        int i = 0;
        public event MyDel _mdl;//唯一不同的是,在这里添加了 关键字 event ,就变成了事件
        private void button1_Click(object sender, EventArgs e)
        {
            i++;
            if (i==3)
            {
                i = 0;
                if (this._mdl!=null)//this。。点出来可以发现——mdl 是一个闪电的图标
                {
                      this._mdl();//调用方法
                }
                
            }
        }
    }
}

总结:

委托和事件的区别

1、委托和事件没有可比性,因为委托是数据类型,事件是对象(可以理解为对委托变量的封装。),下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别。事件的内部是用委托实现的。(举例子:三种实现事件方式的区别(直接用委托实现、用私有委托+公有方法模拟事件,直接用event事件实现))

2、因为对于事件来讲,外部只能“注册自己+=、注销自己-=”,外界不可以注销其他的注册者,外界不可以主动触发事件,因此如果用Delegate就没法进行上面的控制,因此诞生了事件这种语法。add、remove。

3、事件是用来阉割委托实例的。事件只能add、remove自己,不能赋值。事件只能+=、-=,不能=、不能外部触发事件。

总结:

1、委托的作用:

占位,在不知道将来要执行的方法的具体代码时,可以先用一个委托变量来代替方法调用(委托的返回值,参数列表要确定)。在实际调用之前,需要为委托赋值,否则为null。

2、事件的作用:

事件的作用与委托变量一样,只是功能上比委托变量有更多的限制。(比如:1.只能通过+=或-=来绑定方法(事件处理程序)2.只能在类内部调用(触发)事件。)

3、在自定义控件(自己编写控件的时候,会大量用到.编写控件的时候,会写一些事件。但是当这些事件 被触发以后,具体执行的那些事件处理程序是编写控件的人没法确定的。这个时候只能通过事件来占位(调用),具体调用的是哪个方法,由使用控件的人来决定(Click+=new 委托(方法名);))

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 委托————窗体之间传值练习------引出事件的概念

    练习:新建连个窗体,当点击Form1窗体的“传过去”,文本内容就显示在了,第二个窗体中;当点击第二个窗体时候,值又返回到窗体1的文本框中!

    静心物语313
  • 反射案例——记事本插件练习

    静心物语313
  • 什么是多播委托?

    说明:1、多播委托就是对一个声明的委托Mydelegate进行多个同类型的方法的赋值;

    静心物语313
  • 【转】Istio 1.0发布,已生产就绪!

    今天,我们很高兴地宣布 Istio 1.0。这距离最初的 0.1 版本发布已经过了一年多时间了。从 0.1 起,Istio 就在蓬勃发展的社区、贡献者和用户的帮...

    杨振涛
  • NSCTF “表情包” 详细writeup

    偶尔打了一下NSCTF,其中大家比较蒙蔽的有一题,叫“表情包”,是常见的颜文字。 ? 这种叫aaencode(可以把任意js编码成颜文字表情),然后在这里全选复...

    ChaMd5安全团队
  • Docker Swarms 跨主机集群搭建

    JerryWangSAP --- 错误消息 This computer doesn't have VT-X/AMD-v enabled

    HaythamXu
  • 面试官:你知道Spring中有哪些可以让我们扩展的地方么

    大家都知道我这段时间陆续更新了Spring系列源码分析以及各种扩展点的文章,到了今天可以总算可以更新这篇文章了

    Java学习录
  • 机器学习与网络安全(四)概率学基础

    计算机科学所处理的内容大部分是完全确定且必然的,程序员写程序时是假定CPU将完美执行每条指令,硬件错误是非常罕见并在编程阶段几乎不予考虑。

    牛油果
  • 数据中心PUE值的三大消耗源

    数据中心PUE值是评价数据中心能源效率的指标,是数据中心消耗的所有能源与IT负载使用的能源之比。

    黄小U跑跑跑
  • 【模型解读】浅析RNN到LSTM

    我们通常所说的RNN实际上有两种,一种是Recurrent Neural Networks,即循环神经网络,一种是Recursive Neural Networ...

    用户1508658

扫码关注云+社区

领取腾讯云代金券