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

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

一文解析C#中的StringSplitOptions枚举

《一文解析C#中的StringSplitOptions枚举》StringSplitOptions是C#中的一个枚举类型,用于控制string.Split()方法分割字符串时的行为,核心作用是处理分割后... 目录C#的StringSplitOptions枚举1.StringSplitOptions枚举的常用

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Python版本与package版本兼容性检查方法总结

《Python版本与package版本兼容性检查方法总结》:本文主要介绍Python版本与package版本兼容性检查方法的相关资料,文中提供四种检查方法,分别是pip查询、conda管理、PyP... 目录引言为什么会出现兼容性问题方法一:用 pip 官方命令查询可用版本方法二:conda 管理包环境方法

Linux云服务器手动配置DNS的方法步骤

《Linux云服务器手动配置DNS的方法步骤》在Linux云服务器上手动配置DNS(域名系统)是确保服务器能够正常解析域名的重要步骤,以下是详细的配置方法,包括系统文件的修改和常见问题的解决方案,需要... 目录1. 为什么需要手动配置 DNS?2. 手动配置 DNS 的方法方法 1:修改 /etc/res

JavaScript对象转数组的三种方法实现

《JavaScript对象转数组的三种方法实现》本文介绍了在JavaScript中将对象转换为数组的三种实用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录方法1:使用Object.keys()和Array.map()方法2:使用Object.entr

SpringBoot中ResponseEntity的使用方法举例详解

《SpringBoot中ResponseEntity的使用方法举例详解》ResponseEntity是Spring的一个用于表示HTTP响应的全功能对象,它可以包含响应的状态码、头信息及响应体内容,下... 目录一、ResponseEntity概述基本特点:二、ResponseEntity的基本用法1. 创

java中判断json key是否存在的几种方法

《java中判断jsonkey是否存在的几种方法》在使用Java处理JSON数据时,如何判断某一个key是否存在?本文就来介绍三种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目http://www.chinasem.cn录第一种方法是使用 jsONObject 的 has 方法