委托又给我惹麻烦了————记委托链的取消注册、获取返回值

  今天改bug碰到了一个问题,有多个方法注册到了一个事件里去,而这些方法本身又有点儿互斥,因而造成了bug,哥调试半天才发现,郁闷至极,遂复习了以前的知识并进行适当延伸,再将成果记录及分享之,以防他日再犯。
  显然这是一个委托链,那么首先就来回顾下委托链的最初写法了,这里引用上一篇 委托的N种写法,你喜欢哪种? 的部分代码。

  定义委托:

delegate string PlusStringHandle(string x, string y);

定义对应的方法:

        static string plusString(string x, string y){Console.WriteLine("plusString方法被调用......");return x + y;}    

 

  调用:

            PlusStringHandle handle = null;handle += plusString;handle += plusString;string str = handle("aa", "bb");Console.WriteLine("调用委托获取返回值:{0}", str);             Console.WriteLine("委托注册的默认方法名:{0}", handle.Method.Name);

  结果:

  再定义一个方法:

        static string testString(string x, string y){Console.WriteLine("testString方法被调用.......");return x + x + y + y;}

  使用-=:

            PlusStringHandle handle = null;handle += plusString;handle += plusString;handle += testString;handle -= plusString;handle -= testString;string str = handle("aa", "bb");Console.WriteLine("调用委托获取返回值:{0}", str);             Console.WriteLine("委托注册的默认方法名:{0}", handle.Method.Name);

  运行发现仍然调用了 plusString 方法,这就是产生文中开头所说的bug的原因了。

  继续修改Main方法:

            PlusStringHandle handle = null;handle += plusString;handle += plusString;handle += testString;//handle -= plusString;//handle -= testString;handle = testString;  //或者先将handle置为null再使用+=string str = handle("aa", "bb");Console.WriteLine("调用委托获取返回值:{0}", str);             Console.WriteLine("委托注册的默认方法名:{0}", handle.Method.Name);

  这就是我要的结果,让委托不再受以前注册过的方法影响。

=======================分割线 =============================

 

  以下继续来探讨下委托链获取的返回值,如上文所写,直接调用委托只能获取最后一次注册的方法的返回值,那么假如说要获取所有已注册的方法的返回值则有两种方式:

            PlusStringHandle handle = null;handle += plusString;handle += plusString;handle += testString;string str = handle("aa", "bb");Console.WriteLine("调用委托获取返回值:{0}", str); Console.WriteLine("委托注册的默认方法名:{0}", handle.Method.Name);Delegate[] delegates = handle.GetInvocationList();Console.WriteLine("以下遍历获取委托链中的返回值==============================================");foreach (PlusStringHandle d in delegates){Console.WriteLine("调用的方法:{0},获取方法返回值:{1}", d.Method.Name, d("qq", "ww"));}foreach (Delegate d in delegates){//d即为PlusStringHandle类型Console.WriteLine("调用的方法:{0},获取方法返回值:{1}", d.Method.Name, d.DynamicInvoke("qq", "ww"));}

  说是两种方式,其实异曲同工,不同的写法,其中一种是动态调用而已了。

  

转载于:https://www.cnblogs.com/FreeDong/p/3248283.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/274096.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android 第十八课 强大的滚动控件 RecyclerView

步骤: 一、添加依赖库compilecom.android.support:recyclerview-v7:26.1.0 二、在activity_mian.xml中,添加RecyclerView控件,并占据整个页面。 三、把你要在RecyclerView中展示的内容,设置成一个实体类Fruit,接着为Re…

ios即时通讯客户端开发之-mac上安装MySQL

一、安装 到MySQL官网上http://dev.mysql.com/downloads/mysql/,下载mysql可安装dmg版本 比如:Mac OS X ver. 10.7 (x86, 64-bit), DMG Archive 下载完的文件为:mysql-5.6.10-osx10.7-x86_64.dmg 1.点击,安装包里的 2.点击安装 安…

dbus 和 policykit 实例篇(python)

dbus 和 policykit 实例篇(python) 使用policykit 的程序一般都有一个dbus daemon程序来完成相关操作,这个dbus daemon 会在系统注册一个system bus 服务名,用于响应要求root privileged的操作,当dbus请求到达时会先验…

和菜鸟一起学linux之DBUS基础学习记录

转自:http://blog.csdn.net/eastmoon502136/article/details/10044993 D-Bus三层架构 D-Bus是一个为应用程序间通信的消息总线系统, 用于进程之间的通信。它是个3层架构的IPC 系统,包括: 1、函数库libdbus ,用于两个应用程序互…

Android 第二十课 广播机制(大喇叭)----发送自定义广播(包括发送标准广播和发送有序广播)

广播分为两种类型:标准广播和有序广播 我们来看一下具体这两者的具体区别: 1、发送标准广播 我们需要先定义一个广播接收器来准备接收此广播才行,否则也是白发。 新建一个MyBroadcastReceiver,代码如下: package com.example.broa…

八大排序算法

概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。 我们这里说说八大排序就是内部排序。 当n较大,则应采用…

Android 第二十一课 RecyclerView简单的应用之编写“精美”的聊天页面

1、由于我们会使用到RecyclerView,因此首先需要在app/build.gradle当中添加依赖库。如下: apply plugin: com.android.application .... dependencies {....compile com.android.support:recyclerview-v7:26.1.0 } 2、然后开始编写主页面,修该…

JavaScript 第四课 案例研究:JavaScript图片库

主要内容:编写一个优秀的标记文件编写一个JavaScript函数以显示用户想要查看的内容由标记出发函数调用使用几个新方法扩展这个JavaScript函数 学习过DOM,我们用JavaScript和DOM去建立一个图片库。最好的办法是什么呢? 利用JavaScript来建立图…

windows下mongodb安装与使用整理

一、首先安装mongodb 1.下载地址:http://www.mongodb.org/downloads 2.解压缩到自己想要安装的目录,比如d:\mongodb 3.创建文件夹d:\mongodb\data\db、d:\mongodb\data\log,分别用来安装db和日志文件,在log文件夹下创建一个日志文…

USACO4.12Beef McNuggets(背包+数论)

昨天晚上写的一题 结果USACO一直挂中 今天交了下 有一点点的数论知识 背包很好想 就是不好确定上界 官方题解: 这是一个背包问题。一般使用动态规划求解。 一种具体的实现是:用一个线性表储存所有的节点是否可以相加得到的状态,然后每次可以…

Java 循环语句中 break,continue,return有什么区别?

break 结束循环,跳出循环体,进行后面的程序;continue 结束本次循环,进行下次循环;return 跳出循环体所在的方法,相当于结束该方法; 例子: public class whiletrueTest{public static void main(String[] args) {heihei();haha();…

运算放大器单电源应用中的使用齐纳二极管偏置方法

运算放大器单电源应用中的偏置方法除了使用大电阻使运放输出达到电源电压的一半外,还有使用齐纳二极管(稳压管)方法也能得到达到应用目的。 下面就推荐几个齐纳二极管(分别对应着电源电压是15V,12V,9V;5V) …

dpi 、 dip 、分辨率、屏幕尺寸、px、density 关系以及换算

本文转自:http://www.cnblogs.com/yaozhongxiao/archive/2014/07/14/3842908.html 一、基本概念 dip : Density independent pixels ,设备无关像素。 dp :就是dip px : 像素 dpi &#xf…

Java 集合中关于Iterator 和ListIterator的详解

1.Iterator Iterator的定义如下&#xff1a;public interface Iterator<E> {}Iterator是一个接口&#xff0c;它是集合的迭代器。集合可以通过Iterator去遍历集合中的元素。Iterator提供的API接口如下&#xff1a;forEachRemaining(Consumer<? super E> action)&a…

使用xrandr和cvt命令添加自定义的分辨率模式

可以使用xrandr -q命令查看当前支持的分辨率模式: 如果过没有你想要的分辨率模式,则需要自己创建新的分辨率模式,例如,我想要创建800x750的分辨率模式,步骤如下: 1.使用cvt命令创建新的分辨率: 2.使用xrandr –newmode modeline信息(CVT命令产生的结果)创建新的mode: $xra…

Java List集合

我们先看一下jdk1.9对其的描述&#xff1a;什么是List&#xff0c;也就是一个有序集合(序列)。1.List接口 List集合代表一个有序集合&#xff0c;集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素&#xff0c;可以通过索引来访问指定位置的集合元素。 List接口继…

Java Set集合

Set接口什么是Set&#xff0c;就是不包含重复元素的集合。Set是一种不包括重复元素的Collection。它维持它自己的内部排序&#xff0c;所以随机访问没有任何意义。与List一样&#xff0c;它同样允许null的存在但是仅有一个。由于Set接口的特殊性&#xff0c;所有传入Set集合中的…

Java Map集合

Map集合&#xff1a;Map接口Map与List、Set接口不同&#xff0c;它是由一系列键值对组成的集合&#xff0c;提供了key到Value的映射。同时它也没有继承Collection。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value&#xff0c;所以它不能存在相同的…

gsettings命令使用简介

1.gsettings创建项 应用程序可以使用gsettings来保存配置信息&#xff0c;可以通过代码在程序中进行设置、修改gsettings的已有的项&#xff0c;但是不能通过程序代码创建新的gsettings项&#xff0c;gsettings的项的在一个叫做schema的规范文件中创建&#xff0c;schema文档其…

Java 之HashSet、LinkedHashSet、TreeSet比较

4.HashSet、LinkedHashSet、TreeSet比较 Set接口Set不允许包含相同的元素&#xff0c;如果试图把两个相同元素加入同一个集合中&#xff0c;add方法返回false。Set判断两个对象相同不是使用运算符&#xff0c;而是根据equals方法。也就是说&#xff0c;只要两个对象用equals方法…