C#笔记4 详细解释事件及其原型、匿名方法和委托的关系

本文主要是介绍C#笔记4 详细解释事件及其原型、匿名方法和委托的关系,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

匿名方法

定义

匿名方法允许一个与委托关联的代码被内联的写入使用委托的位置。

语法形式

delegate(参数列表)
{代码块
}

前文说过,委托是定义了一个公司,公司专门承接某一类型的任务。

委托的实例化就是公司把任务交给了具体的职员(方法)。

委托可以多播,公司可以同时让两个职员来服务客户。

匿名方法就是一个临时职员,这个职员不用提前招聘,只是临时取用,所以直接出现在代码里临时定义。

//定义一个公司
delegate void Company(string task)
class program
{void wokerwy(string task){dosomething();}static void Main(string[] arg){Company newworker=delegate(string ){dosomething2();}newworker.Invoke("任务1给匿名临时员工");newworker=workerwy;newworker("wy正在工作");}
}

可以看到我们先定义了公司或者说中介的形式,具体干活或者说做事的员工*(方法)还没确定。

我们公司本身就有一个员工,可以处理该任务。还有一个匿名员工临时工,在运行时才定义,被调用。注意:invoke等于直接后面跟括号,事实上编译器在你调用委托的时候会默认调用invoke方法。


事件

事件定义

当某个类的对象在运行中遇到一些特定事件,这些事件需要通知给其他代码或者这个对象的使用者,该怎么办?

当发生某个对象相关的事件使,类要使用事件将这一对象通知给用户,这种通知就叫做引发事件。

委托的存在作为事件传递的道路。

怎么理解?

委托是一系列方法的引用,就好像一个公司或者一个工作室或者一个团队,中间干活的人(方法)可能有很多。

当我们换个方式解释,如果委托变成一个触发事件,所有订阅这个事件的人都对该事件做出反应,也就是,我们原本理解委托是从正面的客户去看的,也就是我们从客户的角度去看,是一个公司里面有很多员工,我们调用这个委托,就相当于调用了所有它引用的方法。

当我们从公司里面的角度来看,此时客户的来访(委托的调用)就像一个事件,当客户来访我们就要触发这个事件并传入参数。然后我们的各种方法都要对其做出反应。

如果把整个事情串联起来我们得到什么样的逻辑:

首先存在一类工作室类型,接收某些要求,给出某些产出。

一个用户知道一个这种工作室,能够访问这个工作室,访问会提出了需求(参数),工作室所有成员会做出相应反应。

对应:

首先申明一个委托类型,接收某些参数,返回某些数值。

一个发布者类含有这个委托的某个实例。发布者能够触发这个委托(事件),触发时会给出参数,之后委托引用的所有方法开始工作。

代码解释:

using daylife;Console.WriteLine("顾客要买什么?");customer cstm = new customer();
worker wy=new worker();
wy.onwork(cstm);
string sth=Console.ReadLine();
cstm.Someonebuysth(sth);
Console.ReadLine();//申明一种委托(专门卖货物的工作室)
public delegate void market(string goods);//日常生活
namespace daylife
{//定义一个(事件的发布者)public class customer{//定义一个公司//委托的发布public market bigmarketservice;//public void Someonebuysth(string goods){Console.WriteLine("有人购物!");if (goods != null)//检查参数是否合法{if (bigmarketservice != null) //如果委托已经订阅了方法(这个超市里有人响应){//响应,也就是调用委托对应的方法bigmarketservice(goods);}}}}public class worker{bool isworking= false;//订阅购买委托事件public void onwork(customer cstm){if(isworking == false){cstm.bigmarketservice += give;}}//定义一个方法,用来响应委托public static void give(string goods){Console.WriteLine("wy给你" + goods);}//取消订阅public void offwork(customer cstm){if (isworking == true){cstm.bigmarketservice -= give;}}}
}

可以看到我们设置了两个类,分别是客户类和工作人员类,客户类拥有对市场(委托的发布)的引用 ,我们的工作人员可以选择在市场上班(工作人员订阅这个委托,此时也可以说委托订阅了工作人员give这个方法。),然后客户访问我们的市场时就会触发市场事件,就会由当前订阅了这个事件的员工响应。

一个类中包含一个委托,这个类中包含触发这个委托的方法。这个类叫做发布者类。

其他类中包含对发布者类的订阅方法,也就是存在将自己的方法附加到发布者类委托的响应这一操作。这个类叫做订阅者类。

可以有多个订阅者类,一个订阅者类可以实例化多个订阅者。

 相信看到这,应该理解了委托是什么。就是一个类将在触发委托时调用自己乃至其他类中的方法,所有订阅了该委托(事件)的方法都会执行。

这个机制很好,委托可以发布在不同的类,不同的类都可以订阅同一个委托,可以灵活的控制要调用的方法。

事件的发布和订阅

在使用委托作为通知其他类执行对应代码时我们会发现,所有拿到这个委托引用的类都可以修改其对应的方法,这让整个结构变得不稳定,如果有一个类中代码写的是:

cstm.bigmarketservice = give;

而不是:

cstm.bigmarketservice += give;

就会导致,之前其他类的订阅失效。

这很明显是不科学的,一个类或者说一个对象应该只能取消自己对这个委托事件的订阅才对。

于是C#提供了专门的事件处理机制,保证事件订阅的可靠性,其做法是在发布的委托定义中加上event关键字,其他代码不变。

public event market bigmarketservice;

这样后面其他的类在获得引用时,只能进行+=或者-=的操作,而不能直接使用=。并且,事件即使是public的,也不能被除了发布者类以外的调用。

如此,解决了一个安全隐患,可以看出,事件就是一种特殊的委托,发布者发布了事件之后,订阅者只能进行自身的订阅或者取消。

委托事件的内置类型和windows事件

见后续。

这篇关于C#笔记4 详细解释事件及其原型、匿名方法和委托的关系的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1123054

相关文章

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

判断PyTorch是GPU版还是CPU版的方法小结

《判断PyTorch是GPU版还是CPU版的方法小结》PyTorch作为当前最流行的深度学习框架之一,支持在CPU和GPU(NVIDIACUDA)上运行,所以对于深度学习开发者来说,正确识别PyTor... 目录前言为什么需要区分GPU和CPU版本?性能差异硬件要求如何检查PyTorch版本?方法1:使用命

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Java中的工具类命名方法

《Java中的工具类命名方法》:本文主要介绍Java中的工具类究竟如何命名,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java中的工具类究竟如何命名?先来几个例子几种命名方式的比较到底如何命名 ?总结Java中的工具类究竟如何命名?先来几个例子JD

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤及问题解决

《IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决》:本文主要介绍IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决,本文分步骤结合实例给大... 目录步骤 1:创建 Maven Web 项目步骤 2:添加 Spring MVC 依赖1、保存后执行2、将新的依赖

python获取网页表格的多种方法汇总

《python获取网页表格的多种方法汇总》我们在网页上看到很多的表格,如果要获取里面的数据或者转化成其他格式,就需要将表格获取下来并进行整理,在Python中,获取网页表格的方法有多种,下面就跟随小编... 目录1. 使用Pandas的read_html2. 使用BeautifulSoup和pandas3.