前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >事件与委托的区别就是“+=”和“-="?

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

作者头像
静心物语313
发布2020-03-24 14:37:03
1.2K0
发布2020-03-24 14:37:03
举报
文章被收录于专栏:静心物语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、下面接着添加一个普通的按钮,

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

Form1代码:

代码语言:javascript
复制
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 代码:

代码语言:javascript
复制
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代码:

代码语言:javascript
复制
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 代码:

代码语言:javascript
复制
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 委托(方法名);))

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 本实验步骤:(明白事件与委托的区别,先用委托来实现!)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档