C#事件与委托

本文详细解析了C#中的委托概念,包括委托的使用、声明方式、存储方法及与事件的区别。通过示例代码,展示了委托如何作为参数传递、如何与匿名方法结合使用,以及委托链的概念。此外,文章还介绍了事件机制的实现方式,以及如何通过事件进行动态设置控件事件。最后,对比了委托与事件的功能差异,帮助开发者更深入地理解二者在不同场景下的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第六部分:委托事件

为什么有委托delegate

委托是一种数据类型,像类一样(可以声明委托类型变量)。方法参数可以是int、string、类类型
•voidM1(intn){  } √
•voidM2(string s){  } √
•voidM3(Person p){  } √

那么能不能把方法也作为参数进行传递?

•voidM4(M1 method){  method();     }   ??能把方法作为参数吗??,如果能,那么把方法作为参数的意义何在?
•使用普通变量的时候是直接取值,或赋值。而使用委托变量的时候,我们还可以直接调用。

l1.委托带给我们的效果(好处)
l2.委托的语法
l3.委托的微观描述
l4.项目中什么时候用委托。
l5.委托的本质。

委托就是一种数据类型,用来存放方法的数据类型。


那么委托到底把方法存到哪里了?其实委托还是一个类。把方法包装成了一个委托。

方法是不能直接赋值的,那么能不能声明一个能存放方法的变量呢(委托)。


委托的使用
声明委托的方式:delegate 返回值类型 委托类型名(参数)
比如delegatevoid StringProcess(string s);
注意这里的除了前面的delegate,剩下部分和声明一个函数一样,但是StringProcess不是函数名,而是委托类型名
存储什么样的方法就声明什么类型(方法参数与返回值)的委托。
声明的委托是一种类型,就像int、Person一样,如果要用的话还要声明委托类型的变量,声明委托类型变量的方式:StringProcess f1;
将委托类型变量指向函数 StringProcess sp= new StringProcess(SayHello),这样就可以像调用普通函数一样把sp当成函数用了。委托可以看做是函数的指针。整数可以用整数变量指向它,对象可以用对象变量指向它,函数也可以用委托变量指向它。和直接调用函数的区别:用委托就可以指向任意的函数,哪怕是之前没定义的都可以,而不使用受限于那几种。
将委托类型变量指向函数还可以简化成StringProcess sp= SayHello,编译器帮我们进行了new。但是不能sp=PrintIt(),因为这样就成了函数调用。

public delegate intxxxDelegate(参数);

public delegate void xxxHandler();

class Person

{

}

Person p=….;

xxxHandlerdel=…;



委托使用案例:字符串数组处理
ldelegatestringProcessDelegate(strings);
 static void ProcessIntArray(ProcessDelegatep)

        {

            string[] values = new string[]{ "aB","Cd"};

            for (int i = 0; i <values.Length; i++)

            {

                values[i] = p(values[i]);

            }

            Console.WriteLine("处理后");

            foreach (stringsin values)

            {

                Console.WriteLine(s);

            }

        }

编写函数,大写、小写、加引号

进一步体会:和直接调用函数的区别:用委托就可以指向任意的函数,哪怕是之前没定义的都可以,而不使用受限于那几种。


匿名方法(*,知道即可)
使用Delegate的时候很多时候没必要使用一个普通的方法,因为这个方法只有这个Delegate会用,并且只用一次,这时候使用匿名方法最合适。
匿名方法就是没有名字的方法。3就是没有名字的int对象。3+5就是两个匿名int对象的相加,允许匿名对象,就允许匿名方法。

 ProcessWordDelegate p = delegate(string s)

            {

                Console.WriteLine(s);

            };

知道C#中有匿名方法,看到这种写法知道是匿名函数即可。

匿名方法与lambda表达式最终编译为一个方法。



多播委托*(委托链,委托的组合)
delegatevoid ProcessWordDelegate(strings)
ProcessWordDelegate d =new ProcessWordDelegate(SayHello)+newProcessWordDelegate(ToLower)
多播委托如何处理返回值?
•委托绑定多个方法后,其中一个方法执行发生异常后面的方法还会继续执行吗?不会!
•一个重要的方法GetInvocationList();//返回一个Delegate[]类型。Delegate类是一个抽象类,是所有委托的父类。
组合的委托必须是同一个类型
相当于创建了一个按照组合的顺序依次调用的新委托对象
委托的组合一般是给事件用的,用普通的委托的时候很少用

 class Program

   {

       static void Main(string[] args)

       {

            UpdateDelegate upde = M1;

            upde += M2;

            upde += M3;

            upde -= M2;

            upde = M4;

            upde();

            Console.ReadKey();

       }

       public static void M1()

       {

            Console.WriteLine("M1");

       }

       public static void M2()

       {

            Console.WriteLine("M2");

       }

       public static void M3()

       {

            Console.WriteLine("M3");

       }

       public static void M4()

       {

            Console.WriteLine("M4");

       }

   }

   public delegate void UpdateDelegate();

==============================================

ResultDelegate M1 = T1;

            M1 += T2;

            M1 += T3;

            M1 += T4;

            int r = M1();

            Console.WriteLine(r);

            Console.ReadKey();

 publicstatic int T1()

       {

            return 1;

       }

       public static int T2()

       {

            return 2;

       }

       public static int T3()

       {

            return 3;

       }

       public static int T4()

       {

            return 4;

       }

public delegate int ResultDelegate();

==========================================

 Delegate[]des=  M1.GetInvocationList();

         foreach (Delegate item in des)

         {

              ResultDelegate res = item as ResultDelegate;

              Console.WriteLine(res());

         }

==================================单独拿到里面每个方法


为委托的增减方法
ld+=SayHello,为委托增加一个方法,不要感觉奇怪,因为它就是d=d+ SayHello
ld-=SayHello,将方法从委托中移除。
lDelegate.Combine();

 public delegate void MyDelegate<T>(T msg);

Action无返回值

Func有返回值


委托的不可变性
委托具有类似于string一样的不可变性。即时窗口中查看地址。
建议使用的时候尽量少定义自己的委托,使用系统中已经有的委托。减少程序集中定义的类型的个数.无参数,无返回值的委托可以用:Action。

委托的本质1(*)
其实就是一个类把方法包装了一下,委托都继承自System.MulticastDelegate,而System.MulticastDelegate又继承自System.Delegate
多播委托就是有一个委托数组,依次调用。
查看自己写的委托的IL代码:

看不到Invoke()方法的代码,该代码由CLR在运行时自动生成。参考备注1.



事件(通过委托实现的,委托才是事件能正常执行的核心内容)
事件语法:event ProcessWordDelegate 例子 OnInt
加了event关键字实现事件机制的好处:用了event事件,不可以修改事件已经注册的值;不可以冒充进行事件通知了。在IntUC类外部就不能通过OnInt(3)的方式调用注册的委托了。只能+=、-=!
课上练习:实现连续点击三次触发TriClick事件的按钮(用UserControl),用EventHandler这个委托就行。注意不要把判断次数的代码写到用控件的窗口上,否则就违反了封装的原则。
动态设置控件事件

事件本质论
event会自动生成一个private delegate变量和两个函数: addremoveC#编译器用这两个方法支持+=-=操作符 (*)C#<>.Net
publicevent MyDelegate OnEvent;
内部实现是(示例性)
privateMyDelegate OnEvent;
publicvoid Add(MyDelegate d)
{
  OnEvent+=d;
}
publicvoid Remove(yDelegate d)
{
   OnEvent-=d;
}
因为OnEvent是private的,所以在类外部不能OnEvent(1)触发事件,但是在类内部可以。
public的方法只有Add和Remove,所以只能+=、-=,其他的操作都是不可以的。


委托和事件的区别(常考)
    委托和事件没有可比性,因为委托是数据类型,事件是对象(可以理解为对委托变量的封装。),下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别。事件的内部是用委托实现的。(举例子:三种实现事件方式的区别(直接用委托实现、用私有委托+公有方法模拟事件,直接用event事件实现))
     因为对于事件来讲,外部只能“注册自己+=、注销自己-=”,外界不可以注销其他的注册者,外界不可以主动触发事件,因此如果用Delegate就没法进行上面的控制,因此诞生了事件这种语法。add、remove。
    事件是用来阉割委托实例的。事件只能add、remove自己,不能赋值。事件只能+=、-=,不能=、不能外部触发事件。


委托与事件总结
委托的作用:
•占位,在不知道将来要执行的方法的具体代码时,可以先用一个委托变量来代替方法调用(委托的返回值,参数列表要确定)。在实际调用之前,需要为委托赋值,否则为null。
事件的作用:
•事件的作用与委托变量一样,只是功能上比委托变量有更多的限制。(比如:1.只能通过+=或-=来绑定方法(事件处理程序)2.只能在类内部调用(触发)事件。)
在自定义控件(自己编写控件的时候,会大量用到.编写控件的时候,会写一些事件。但是当这些事件被触发以后,具体执行的那些事件处理程序是编写控件的人没法确定的。这个时候只能通过事件来占位(调用),具体调用的是哪个方法,由使用控件的人来决定(Click+=new委托(方法名);))































【基于QT的调色板】是一个使用Qt框架开发的色彩选择工具,类似于Windows操作系统中常见的颜色选取器。Qt是一个跨平台的应用程序开发框架,广泛应用于桌面、移动和嵌入式设备,支持C++和QML语言。这个调色板功能提供了横竖两种渐变模式,用户可以方便地选取所需的颜色值。 在Qt中,调色板(QPalette)是一个关键的类,用于管理应用程序的视觉样式。QPalette包含了一系列的颜色角色,如背景色、前景色、文本色、高亮色等,这些颜色可以根据用户的系统设置或应用程序的需求进行定制。通过自定义QPalette,开发者可以创建具有独特视觉风格的应用程序。 该调色板功能可能使用了QColorDialog,这是一个标准的Qt对话框,允许用户选择颜色。QColorDialog提供了一种简单的方式来获取用户的颜色选择,通常包括一个调色板界面,用户可以通过滑动或点击来选择RGB、HSV或其他色彩模型中的颜色。 横渐变取色可能通过QGradient实现,QGradient允许开发者创建线性或径向的色彩渐变。线性渐变(QLinearGradient)沿直线从一个点到另一个点过渡颜色,而径向渐变(QRadialGradient)则以圆心为中心向外扩散颜色。在调色板中,用户可能可以通过滑动条或鼠标拖动来改变渐变的位置,从而选取不同位置的颜色。 竖渐变取色则可能是通过调整QGradient的方向来实现的,将原本水平的渐变方向改为垂直。这种设计可以提供另一种方式来探索颜色空间,使得选取颜色更为直观和便捷。 在【colorpanelhsb】这个文件名中,我们可以推测这是HSB(色相、饱和度、亮度)色彩模型相关的代码或资源。HSB模型是另一种常见且直观的颜色表示方式,RGB或CMYK模型不同,它以人的感知为基础,更容易理解。在这个调色板中,用户可能可以通过调整H、S、B三个参数来选取所需的颜色。 基于QT的调色板是一个利用Qt框架和其提供的色彩管理工具,如QPalette、QColorDialog、QGradient等,构建的交互式颜色选择组件。它不仅提供了横竖渐变的色彩选取方式,还可能支持HSB色彩模型,使得用户在开发图形用户界面时能更加灵活和精准地控制色彩。
标题基于Spring Boot的二手物品交易网站系统研究AI更换标题第1章引言阐述基于Spring Boot开发二手物品交易网站的研究背景、意义、现状及本文方法创新点。1.1研究背景意义介绍二手物品交易的市场需求和Spring Boot技术的适用性。1.2国内外研究现状概述当前二手物品交易网站的发展现状和趋势。1.3论文方法创新点说明本文采用的研究方法和在系统设计中的创新之处。第2章相关理论技术介绍开发二手物品交易网站所涉及的相关理论和关键技术。2.1Spring Boot框架解释Spring Boot的核心概念和主要特性。2.2数据库技术讨论适用的数据库技术及其在系统中的角色。2.3前端技术阐述后端配合的前端技术及其在系统中的应用。第3章系统需求分析详细分析二手物品交易网站系统的功能需求和性能需求。3.1功能需求列举系统应实现的主要功能模块。3.2性能需求明确系统应满足的性能指标和安全性要求。第4章系统设计实现具体描述基于Spring Boot的二手物品交易网站系统的设计和实现过程。4.1系统架构设计给出系统的整体架构设计和各模块间的交互方式。4.2数据库设计详细阐述数据库的结构设计和数据操作流程。4.3界面设计实现介绍系统的界面设计和用户交互的实现细节。第5章系统测试优化说明对系统进行测试的方法和性能优化的措施。5.1测试方法步骤测试环境的搭建、测试数据的准备及测试流程。5.2测试结果分析对测试结果进行详细分析,验证系统是否满足需求。5.3性能优化措施提出针对系统性能瓶颈的优化建议和实施方案。第6章结论展望总结研究成果,并展望未来可能的研究方向和改进空间。6.1研究结论概括本文基于Spring Boot开发二手物品交易网站的主要发现和成果。6.2展望改进讨论未来可能的系统改进方向和新的功能拓展。
1. 用户权限管理模块 角色管理: 学生:查看个人住宿信息、提交报修申请、查看卫生检查结果、请假外出登记 宿管人员:分配宿舍床位、处理报修申请、记录卫生检查结果、登记晚归情况 管理员:维护楼栋房间信息、管理用户账号、统计住宿数据、发布宿舍通知 用户操作: 登录认证:对接学校统一身份认证(模拟实现,用学号 / 工号作为账号),支持密码重置 信息管理:学生完善个人信息(院系、专业、联系电话),管理员维护所有用户信息 权限控制:不同角色仅可见对应功能(如学生无法修改床位分配信息) 2. 宿舍信息管理模块 楼栋房间管理: 楼栋信息:名称(如 "1 号宿舍楼")、层数、性别限制(男 / 女 / 混合)、管理员(宿管) 房间信息:房间号(如 "101")、户型(4 人间 / 6 人间)、床位数量、已住人数、可用状态 设施信息:记录房间内设施(如空调、热水器、桌椅)的配置完好状态 床位管理: 床位编号:为每个床位设置唯一编号(如 "101-1" 表示 101 房间 1 号床) 状态标记:标记床位为 "空闲 / 已分配 / 维修中",支持批量查询空闲床位 历史记录:保存床位的分配变更记录(如从学生 A 调换到学生 B 的时间原因) 3. 住宿分配调整模块 住宿分配: 新生分配:管理员导入新生名单后,宿管可按专业集中、性别匹配等规则批量分配床位 手动分配:针对转专业、复学学生,宿管手动指定空闲床位并记录分配时间 分配结果公示:学生登录后可查看自己的宿舍信息(楼栋、房间号、床位号、室友列表) 调整管理: 调宿申请:学生提交调宿原因(如室友矛盾、身体原因),选择意向宿舍(需有空位) 审批流程:宿管审核申请,通过后执行床位调换,更新双方住宿信息 换宿记录:保存调宿历史(申请人、原床位、新床位、审批人、时间) 4. 报修安全管理模块 报修管理: 报修提交:学生选择宿舍、设施类型(如 "
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值