还弄不明白【委托和事件】么?看这一篇就足够了!!!

2023-05-16

这两个概念长时间不用了,今天看到CAD二次开发中用到了自定义事件,有点迷糊了,索性再整理一下加深印象!

一说到委托和事件,他们总是绑定在一起的不可分割!可能你会说啊!这有什么用啊?尽管你没有在意,但是只要你编写C#程序,就会潜移默化的使用委托和事件,这也是多态的一种表现形式。有关多态,我们后续再说。本节力求通俗易懂的让你明白委托和事件的关系,并能自己去编写,即使不去编写也能看懂C#中的代码。


目录

1.委托:

1.1使用委托的步骤:

1.2程序应用:

①声明委托

②根据委托定义方法

③定义委托变量

 ④调用委托变量

 ⑤将委托变量和具体的方法关联挂载

 1.3程序效果:

 1.4补充:

 2.事件:

2.1使用事件的步骤:

2.2程序应用:

2.2.1声明委托:

 2.2.2根据声明的委托定义具体的方法:

2.2.3添加事件:

​ 2.2.4使用事件:

​ 2.2.5将事件与具体的方法挂载:

2.3程序效果:

 3.事件与委托总结:

 4.看看微软自定义和CAD二次开发的事件吧:

 5.总结:


 1.委托:

比喻:委托(delegate)就是代理、中介,比如你自己因为某种原因办不了的事,就需要中介去做!

在程序中委托可以看成是一种数据类型【你可以把他看成你的自定义类】,他可以定义变量。但是他是一种特殊的变量,因为这个变量只能接收方法。

1.1使用委托的步骤:

总结下使用委托中主要有五个步骤:

①声明委托【类似抽象方法的声明,没有具体的方法体】

②根据声明的委托定义具体的方法

③定义委托变量

④调用委托

⑤将委托变量和具体的方法关联挂载

1.2程序应用:

我目前有个需求,就是想实现窗体之间的双向通信。

基本想法如下:通过窗体A创建一个窗体B,让A发送的消息在B中接收。在B中的消息也能发送到A中。很简单对吧,熟悉C#的同学会说,直接调用实例就好了啊或者静态变量存一下啊!先说实例那个,其实A的消息给B是可以的,因为B就是A创建的。但是反过来就不行了。再说静态方法,一个程序中如果静态方法多了,一是不好找二是也会影响一丢丢的性能(暂且不管,因为委托更大的作用还在后头,只是用这个例子说明)。

程序界面:

 form1是我的主窗体(form1),form2是我创建的子窗体(frmSub1)。先实现子窗体向主窗体发送消息的功能。

 

①声明委托

 首先在form1窗体中声明委托【返回值类型和参数个数及类型是要与将来关联的方法一致的】,因为我只展示信息,所以设置为void没有问题。信息本身是字符串,所以参数string可以的。

 委托原则上定义在类的外面,和类本身平级

②根据委托定义方法

在form1主窗体中定义方法用来展示子窗体传递的信息。(方法的返回值和参数个数类型要和声明委托的一致)

 

③定义委托变量

切换到子窗体,在frmSub1中定义委托变量(直接声明就好),这里就能看出委托和类一样,能作为类型去定义变量。

 ④调用委托变量

在frmSub1中的发送按钮事件中调用委托变量,并传入具体的内容。这里你可以想想,子窗体压根不知道父窗体要用什么方法,反正我就用你定义的委托类型创建的变量就好了,你要什么参数我给你,至于什么方法去和他关联,我就管不着了。

 ⑤将委托变量和具体的方法关联挂载

 再次返回主窗体form1中,将子窗体frmSub1中的委托变量和form1中的方法关联一下。就可以实现了。

 1.3程序效果:

那么反过来主窗体给子窗体通信我相信大家可以自己尝试了。

注意:

因为委托基本都是在不同的文件之间进行的,所以使用委托的五个步骤基本是分开的,很多人刚开始分不清在哪里定义那些,我就把我的方式说一下吧,其实用多了懂原理了就不用刻意记了。

①声明委托一般在父级,在哪无所谓,因为public,但是要记住要好找,后期维护方便

②根据委托定义方法,一般就是哪里用这个方法,就定义在哪里。

③定义委托变量的位置要和委托方法定义的位置分开,因为你要通过委托变量调用具体方法。

④在定义委托变量的地方去使用委托变量。

⑤关联还是通过实例对象进行关联,只要能将委托变量和具体方法挂上就好。

 

 1.4补充:

其实用了委托你就可以发现委托挂载的方法可以不止一个,用“+=”或者“=”挂载,用“-=”卸载方法。

也不用new 委托,直接将方法名放上就行了(心里要明白)。

比如:

 2.事件:

说完了委托,那么事件又是什么呢?

事件就是对象在外界的“刺激”下而对外界提供的一种消息机制。

其实事件就是对委托的进一步封装,因为委托暴露了太多的权限,用事件对他进行限制(比如什么能改,什么不能改)。

我的理解就是:事件就是对正常委托进行了限制的委托。

事件中你要明白几个概念:

发送者:即对象本身,当本身状态发生改变的时候,事件触发并通知事件的接收者。

接收者:用来处理事件的,发送者发送事件后会自动执行的内容。

2.1使用事件的步骤:

使用事件也是一样五个步骤:

①声明委托

②根据声明的委托定义具体的方法

③添加事件

④使用事件

⑤将事件与具体的方法挂载

2.2程序应用:

如果刚才的需求用事件实现是如何呢?

2.2.1声明委托:

和委托一样在主窗体form1中声明一个委托:

 2.2.2根据声明的委托定义具体的方法:

在主窗体form1中添加一个方法(和委托要求一样)

 

2.2.3添加事件:

在子窗体frmSub1定义事件:

可以发现这个定义事件就是委托的定义委托变量加了个event标识符。

2.2.4使用事件:

在子窗体frmSub1发送按钮中使用定义的事件(和委托一样)

2.2.5将事件与具体的方法挂载:

再次回到主窗体form1将事件与具体方法挂载。

注意:这里只能用+=,不能用=

这里就是对委托进行的限制,防止你覆盖掉原来挂载的方法,你自己后定义的方法只能+=或-=,而不能直接覆盖。

试想如果让覆盖,那么C#系统定义好的可能就因为你的误操作都没了!!!

2.3程序效果:

可以发现与委托是一样的。

 

 3.事件与委托总结:

前面说了这么多还是做个简短的汇总:

事件就是对委托进行进一步的封装,对委托强大的对外开放的权限进行一个设定。

事件主要对委托起到一个保护作用,其本质还是委托。

事件对某一个对象本身来说是私有的,因此只能通过+=和-=方式赋值。

 4.看看微软自定义和CAD二次开发的事件吧:

看到这里了,相信你已经对委托和事件已经有了一个较为全面的认识了,接下来看看系统自定义的吧。

 找到一个微软定义的按钮事件,click就是定义的一个事件。

 进一步找,EventHandler就是一个委托。再继续

可以看到EventHandler真的是一个委托。

 this.btnSend_click是和委托相关联的方法,看一下这个方法参数返回类型是不是和委托定义的一样?【所以当你只删除了这个方法的时候,在运行程序,ide会报错就是这个原因,因为你把事件挂载的方法实体删掉了,编译器根据挂载的方法名找不到实体方法了】

 看到这里你就恍然大明白了吧?其实事件挂载也可以不必new个委托,直接放也是可以的。

这两种方法是等效的。


我们在看一个CAD二次开发中的委托吧?

文档说这个CurveSnap捕捉是AddObjectSnapInfo的委托,那我们来进一步的看看是不是?

 ApplyToEntityType第二个参数就相当于声明委托变量了。

 可以看到delegate就是委托声明,并且方法返回值和参数类型和个数是一致的。在回头看那个CurveSnap方法不就是根据委托定义的方法么?将方法名放入ApplyToEntityType参数中就是实现了委托变量和方法的关联。


再来看最后一个例子:

CAD二次开发中鼠标停留显示需要添加鼠标事件。

 不难分析出,PointMonitor就是在Editor类中声明的事件,而PointMonitorEventHandler就是一个委托,ed_PointMonitor就是与这个委托相关联的方法!依次看图!

 5.总结:

相信看到最后你一定对委托和事件有了一个十分深入的了解了。欢迎大家留下宝贵意见。关于面向对象其他内容后续我会陆续总结,欢迎大家关注!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

还弄不明白【委托和事件】么?看这一篇就足够了!!! 的相关文章

  • PG-REINFORCE tensorflow 2.0

    REINFORCE 算法实现 REINFORCE算法是策略梯度算法最原始的实现算法 xff0c 这里采用tensorflow2 0进行实现 span class token keyword import span tensorflow sp
  • DDPG tensorflow 2.0

    DDPG算法的tensorflow2 0实现 算法的详细解析可以看DDPG解析 span class token keyword import span tensorflow span class token keyword as span
  • MADDPG tensorflow2.0

    MADDPG 的 tensorflow2 0实现 环境 MPE 对MPE环境进行了一些简单的修改 xff0c 目前只在MPE中的simple spread上进行了简单的测试 MADDPG代码 代码由于是自己写的 xff0c 可能有一些错误
  • 最短探索时间的一种想法——MADDPG

    前言 最近在做maddpg相关的项目时候 xff0c 涉及到了一些在固定地图的场景下 xff0c 采取何种探索方式 xff0c 能够使在最短的时间内 xff0c 探索尽可能多的地图内容 xff0c 对此做了一些努力 xff0c 一些朋友对此
  • 在NVIDIA Jetson Xavier NX上使用tensorflow-gpu

    在NVIDIA Jetson Xavier NX上使用tensorflow gpu 目前所做的项目需要在NVIDIA Jetson Xavier NX的ubuntu18 04的系统下配置ROS xff0c python3以及tensorfl
  • CSDN最全数学公式

    CSDN中的数学公式 1 加减乘除 a 43 b a 43 b a 43 b xff1a a 43 b a
  • 数据结构体系复构

    1 数组 数组是可以再内存中连续存储多个元素的结构 xff0c 在内存中的分配也是连续的 xff0c 数组中的元素通过数组下标进行访问 xff0c 数组下标从0开始 数组运算 xff1a 遍历 xff1a 遍历所有元素并进行打印 插入 xf
  • 指向void的指针

    万能指针 一个指向任何对象类型的指针都可以赋值给类型为void 的变量 xff0c void 可以赋值给另外一个void xff0c 俩个void 可以比较相等与否 xff0c 而且可以显式地将void 转换到另一个类型 其他操作都是不安全
  • nano 命令

    Nano命令指南 打开文件与新建文件 使用nano打开或新建文件 xff0c 只需键入 xff1a 代码 1 1 打开或新建文件 nano 文件名 Nano是一种单模式编辑器 xff0c 你可以直接输入文字 如果你要编辑一个像 etc fs
  • 四轴飞控pid simulink仿真

    今天是我写的第一篇博客hhh xff0c 可能文章思路混乱 xff0c 大家海涵 最近想自己用stm32搞一个四轴飞行器的飞控 xff0c 现在进展比较缓慢 xff0c 主要受制于想做一个wifi无线透传的视频实时传递 用了一个新的模块 x
  • 蓝桥杯嵌入式客观题总结

    一 CPU芯片 xff1a STM32F103RBT6 STM32 xff1a 32位的MCU xff08 ST 意法半导体公司 M xff1a 微控制器 32 xff1a 32bit xff09 F 61 通用类型 103 xff1a 中
  • 大学Python编程试卷真题!用python循环,输出1+11+111+1111+11111的值

    你用过的Python的库有哪些 分别用于工作中什么场景 这个是上一期讲的面试题拓展 那今天来再拓展一下 xff0c 讲一个算法题 利用python循环 xff0c 输出1 43 11 43 111 43 1111 43 11111的值 这个
  • Dockerfile 部署springboot 项目暨保留字指令讲解

    Dockerfile 部署springboot 项目暨保留字指令讲解 一 系统环境二 springboot 项目部署2 1 springboot 项目准备2 2 上传jar2 3 编写dockerfile 文件2 4 构建镜像并运行 三 保
  • ubuntu系统使用LVM,实现减小root分区并扩充swap交换分区(至最大8G)

    xff08 在安装系统时安装LVM逻辑卷管理 1 减小root分区 无法在线缩减root分区系统文件大小 xff0c 必须进入救援模式 xff08 使用启动盘 xff09 在救援模式下 xff0c 打开终端 执行 sudo lvscan 或
  • SLAM机器人开发(五)使用Improved_ORBSLAM2实时稠密重建教程

    使用Improved ORBSLAM2实时稠密重建教程 搭建ROS环境安装依赖库运行ORBSLAM2 App转换为Octomap地图并实现导航 在 SLAM机器人开发专栏中 xff0c 上一篇介绍了ORBSLAM的原理和一系列开源库 xff
  • ROS系列书籍--机械工业出版社

    ROS系列书籍 机械工业出版社 1 ROS机器人开发实践 xff08 作者 xff1a 胡春旭 xff09 2 机器人ROS开发实践 xff08 作者 xff1a 无为斋主 xff09 3 ROS机器人编程实践 xff08 作者 xff1a
  • 问题解决-----解决ROS程序注册(source devel/setup.bash)只在当前终端生效的问题

    64 TOC 解决ROS程序注册 source devel setup bash 只在当前终端生效的问题目录 在进行ROS的嵌入式编程的时候 xff0c 每次程序编写完成 xff0c 都需要进行编译 xff0c 这是ROS嵌入式开发的必要步
  • ROS学习【10】-----搭建Gazebo机器人物理仿真环境并展示空环境中的机器人

    ROS学习 搭建Gazebo机器人物理仿真环境并展示空环境中的机器人模型目录 一 运行Gazebo 查看是否能够正常打开程序1 新建一个终端 xff0c 运行Gazebo仿真软件2 应对Gazebo程序闪退的方法 二 搭建Gazebo机器人
  • 问题解决-----ROS中Gazebo学习的问题解决合集(初次运行黑屏、运行launch文件后闪退、黑屏;gazebo联合rviz出现process has died等的解决办法)

    问题解决 ROS中gazebo环境搭建学习的问题解决合集目录 一 初次运行Gazebo出现黑屏1 问题描述 xff1a 2 问题原因3 解决方法 二 编译gazebo的功能包出现编译错误1 问题描述2 问题原因3 解决方法 三 运行laun
  • TCP传输大文件(图片、文档)

    遇到TCP传输大文件问题 xff0c 主要是 xff08 1 xff09 传输快 xff0c 但拼接成的大文件数据错 xff08 2 xff09 加校验 xff0c 传输变慢 xff08 3 xff09 接收包数跟发送包数不对应 费了一段时

随机推荐

  • ROS学习【14】-----利用ROS中的导航框架(move_base,amcl),实现基于gazebo仿真机器人的自主导航

    64 TOC 上次的ROS学习 xff0c 我们通过SLAM框架下的gmapping及hector slam实现了手动控制我们Gzebo仿真机器人进行地图的规划 xff0c 并保存了相应的地图 xff0c 那么如何让自己人按照我们规划的路线
  • 抛出异常的简单处理

    span class token keyword function span span class token function func span span class token punctuation span span class
  • 进程切换过程

    在每个进程都有一个进程控制块 xff08 PCB xff09 进程主要分为 创建状态 xff0c 就绪状态 xff0c 运行状态 xff0c 阻塞状态 xff0c 结束态 PCB控制块是以链表方式存放 xff0c 就绪进程的PCB放置在同一
  • 第七篇(上),LQR工程化总结

    目录 一 引言 二 LQR 2 1 LQR的理解与实现 2 1 1 模型设计与实现 2 1 2 LQR工程实现步骤 2 2 参考资料 2 2 1 基础理论与模型的推导 2 2 2 Refer to Apollo 2 2 3 其它实例参考 2
  • STM32工程创建的快速方法

    1 Project gt New Project 2 打开新创建的工程的所在目录 xff0c 删除掉目录中的两个文件夹 xff0c 新创建4个文件夹 xff0c 分别是 xff1a USER CODE OBJ STM32F10 xFWLib
  • Ubuntu18.04下ROS的安装教程、rosdep init问题亲测解决方案

    一 确定自己的Ubuntu版本号 xff0c 并且安装正确的ros版本 lsb release a 查看ubuntu版本 二 更新源 sudo sh c 39 etc lsb release amp amp echo 34 deb http
  • MySQL相关面试题总结

    1 解释一下单列索引和联合索引 单列索引是指在表的某一列上创建索引 联合索引是在多个列上联合创建索引 单列索引可以出现在where条件的任何位置 而联合索引需要按照一定的顺序来写 在多条件查询的时候 联合索引的效率更高 我们联合索引也最多创
  • 修改firefox浏览器滚动条的样式

    最近做了一个网站的项目 xff0c 使用原生的滚动条 ie和谷歌都显示的好好的 xff0c 火狐的滚动条样式没有生效 原因 xff1a 火狐浏览器没有提供原生滚动条的方法和属性 后来浏览器升级之后提供了部分可以修改样式的属性 属性较多 xf
  • jetson nx ssd镜像克隆

    1 打开disk查看要克隆的ssd名称 2卸载ssd 制作镜像 sudo umount dev sdb1 sudo s sudo dd if 61 dev sdb1 conv 61 sync noerror bs 61 64k gzip c
  • Android 关于IPV6 DNS的问题

    目前在测试IPV6 DNS解析的时候发现一个问题 xff0c 这里记录一下 问题是 xff1a 当dhcpv6服务器分配的IPV6 dns是fe80类型的dns时 xff0c 无法发送dns请求 xff0c 抓包看不到有目标地址为fe80
  • PX4开发环境搭建

    PX4开发环境搭建 编译工具链的安装vscode 编译工具链的安装 下载ubuntu sh requirements txt wget https raw githubusercontent com PX4 Firmware master
  • TFmini在nora+(px4)上的使用和验证

    目标 xff1a 使用tfmini完成定高实验 设置 xff1a 1 sens tfmini cfg 设置为telem2 xff08 可修改为其他 xff0c 保证硬件连线一致 xff0c 1一般是无线数传所以没改过去 其他的对应在官网里有
  • ROS | Realsense中的IMU解算orientation

    文章目录 概述 一 定义介绍 二 操作教程 一 下载并编译imu tools功能包 1 创建工作空间并初始化 2 下载imu tools并编译 二 修改配置 1 修改imu tools源码 2 修改launch文件 3 启动解算 概述 本文
  • prometheus服务监控之mysql监控

    文章目录 上传解压安装mysqld exporter安装mariadb在数据库里创建mysql账号用户收集数据在mysql exporter中设置mysql配置信息启动mysql exporter配置prometheus拉取mysql节点信
  • HTTP请求头Authorization

    今天部署了一个Authorization项目 xff0c 由于改了auth服务器客户端id和密码 xff0c 而前端请求header没有修改 xff0c 登录时一直弹框要求输入用户名和密码 xff0c 输入后却无效 xff0c 只好改前端代
  • c语言编程规范第三部分

    3 头文件应向稳定的方向包含 头文件的包含关系是一种依赖 xff0c 一般来说 xff0c 应当让不稳定的模块依赖稳定的模块 xff0c 从而当不稳定的模块发生变化时 xff0c 不会影响 xff08 编译 xff09 稳定的模块 就我们的
  • 看完《C++ primer》后,我都收获了什么?

    文章目录 1 语言只是一个工具2 光学会一门语言还不够3 结语 迫于读研和未来就业的压力 xff0c 我研一上自学了C 43 43 的这门语言 xff0c 自我感觉比较认真的看完了 C 43 43 primer 这本书的大部分章节 xff0
  • Ubuntu18.04 ROS Melodic版本安装gazebo_ros_pkgs包

    疫情期间宅在家没法做实验 xff0c 只能上手gazebo做仿真 xff0c 导入实验室机器人的相关文件后 xff0c 打算看看效果 xff0c 运行代码 roslaunch probot gazebo probot anno gazebo
  • vim如何批量注释

    1 ctrl 43 v 进入 2 按箭头 选中要注释的首行 3 按下大写 i 进入插入模式 4输入 按esc 就可以看到如下内容
  • 还弄不明白【委托和事件】么?看这一篇就足够了!!!

    这两个概念长时间不用了 xff0c 今天看到CAD二次开发中用到了自定义事件 xff0c 有点迷糊了 xff0c 索性再整理一下加深印象 xff01 一说到委托和事件 xff0c 他们总是绑定在一起的不可分割 xff01 可能你会说啊 xf