写在最前面:
        无论是用什么编程语言编写应用程序,都会涉及到函数调用之间的问题。而调用过程可以分为两种,一种是主动请求调用,一种是被动等待调用。这也就是我们常说的调用与回调。下面我将说明DotNet(C#)关于函数回调的实现分析。

一、DotNet(C#)函数回调。
        在DotNet中实现函数调用是通过委托(delegate)实现的,首先你要声明委托原型:

delegate void Notify( int newValue );

这样就声明了一个委托,那到底什么是委托呢?其实委托就是一个回调函数(更确切的说委托是一个安全的函数指针)。当需要回调的时候。可以调用委托的成员函数 Invoke 就可以实现调用你设置的回调函数。这时Invoke会自动根据你声明的委托形式进行调用。在这里我们举一个例子,压力计、报警器的例子:

当压力计的压力指数变化的时候,报警器会报警,并打印出变化的压力值。代码如下

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4
 5namespace ConsoleApplication2
 6{
 7    // 这里声明委托
 8    public delegate void Notify( int newValue );
 9
10    // 压力计
11    class Piezometer
12    {
13        // 压力值
14        private int m_PressureNumber;
15        public int PressureNumber
16        {
17            get
18            {
19                // 返回当前压力值
20                return this.m_PressureNumber;
21            }
22            set
23            {
24                // 设置新的压力值
25                this.m_PressureNumber = value;
26                // 判断是否有人注册该事件,如果有就调用并传入新的压力值。
27                if (OnPressureChanged != null)
28                {
29                    // 这里就是DotNet框架实现的委托好处,它可以根据
30                    // 声明的形式自动匹配调用的参数表和返回值。
31
32                    // 调用回调事件,将新的压力值传入
33                    OnPressureChanged.Invoke(value);
34                }
35            }
36        }
37
38        // 声明一个事件,当压力值变化的时候触发该事件
39        public event Notify OnPressureChanged;
40    }
41
42    // 报警器
43    class Alerter
44    {
45        // 设置监听的压力计
46        public void Listen(Piezometer piezometer)
47        {
48            // 注册压力计压力变化事件
49            piezometer.OnPressureChanged += new Notify(OnChanged);
50        }
51        // 这里就是压力计变化后调用的函数
52        public void OnChanged(int newValue)
53        {
54            // 打印出新的压力值
55            Console.WriteLine(string.Format("New PressureNumber is {0}.", newValue));
56        }
57    }
58
59    class Program
60    {
61        static void Main(string[] args)
62        {
63            Alerter alerter = new Alerter();
64            Piezometer piezometer = new Piezometer();
65
66            // 安装压力计,进行监听
67            alerter.Listen(piezometer);
68
69            // 设置新的压力值,报警器就会打印出新的压力值。
70            piezometer.PressureNumber = 10;
71        }
72    }
73}
74

根据上面的代码我们可以实现自己的自定义事件。(感叹:DotNet框架真是太便利了,声明委托之后,委托的调用方法会自动变成声明的形式。C++就不支持这种操作。下面我会讲一下C++的实现方法。)
在这里我们用Reflector反编译一下Delegate类,该类是委托类型的基类。然而,只有系统和编译器可以显式地从 Delegate 类或 MulticastDelegate 类派生。此外,还不允许从委托类型派生新类型。Delegate 类不是委托类型,该类用于派生委托类型。而我们实现的都是MulticastDelegate派生类型,这样就可以产生一个委托多播的类型。最基本的实现 是

1protected virtual object DynamicInvokeImpl(object[] args)
2{
3    RuntimeMethodHandle methodHandle = new RuntimeMethodHandle(this.GetInvokeMethod());
4    RuntimeMethodInfo methodBase = (RuntimeMethodInfo) RuntimeType.GetMethodBase(Type.GetTypeHandle(this), methodHandle);
5    return methodBase.Invoke(this, BindingFlags.Default, null, args, null, true);
6}
7

当委托被调用时会产生一个运行时方法对象。并通过运行时对象调用

1[MethodImpl(MethodImplOptions.InternalCall), DebuggerStepThrough, DebuggerHidden]
2private extern object _InvokeMethodFast(object target, object[] arguments, ref SignatureStruct sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner);

通知VM进行系统执行方法体。而在多播委托里包含一个_invocationList实现了保存多个委托,使之内部可以循环调用进行广播。

深入探索面向对象事件(Delegate)机制相关推荐

  1. 文化袁探索专栏——事件分发机制

    文化袁探索专栏--Activity.Window和View三者间关系 文化袁探索专栏--View三大流程#Measure 文化袁探索专栏--View三大流程#Layout 文化袁探索专栏--消息分发机 ...

  2. 文化袁探索专栏——消息分发机制

    文化袁探索专栏--Activity.Window和View三者间关系 文化袁探索专栏--View三大流程#Measure 文化袁探索专栏--View三大流程#Layout 文化袁探索专栏--消息分发机 ...

  3. Android 事件传递机制总结

    Android 事件传递机制总结 Android View虽然不是四大组件,但是其重要程度堪比四大组件.初级工程师到中高级工程师,这些都是很重要的,因为事件分发机制面试也会经常被提及,如果我们能get ...

  4. Android事件分发机制详解

    2019独角兽企业重金招聘Python工程师标准>>> 之前在学习Android事件方法机制的时候,看过不少文章,但是大部分都讲的不是很清楚,我自己理解的也是云里雾里,也尝试过阅读源 ...

  5. Nordic系列芯片讲解九 (BLE事件回调机制解析)

    BLE事件回调机制解析 nRF5 SDK从版本14开始,对事件回调机制做了更新,引入了观察者模式,以解耦不同BLE Layer对BLE事件的回调函数. 实现这套机制用到了Flash的段(Section ...

  6. Android事件分发机制:基础篇:最全面、最易懂

    如何提升安卓水平?安卓开发者必须了解的事件分发机制. 最全面.最易懂的形式来讲解Android事件分发机制. 0. 前言 鉴于安卓分发机制较为复杂,故分为多个层次进行讲解,分别为基础篇.实践篇与高级篇 ...

  7. Android View系列(二):事件分发机制源码解析

    概述 在介绍点击事件规则之前,我们需要知道我们分析的是MotionEvent,即点击事件,所谓的事件分发就是对MotionEvent事件的分发过程,即当一个MotionEvent生成以后,系统需要把这 ...

  8. Android 系统(218)---Android的事件分发机制以及滑动冲突的解决

    Android的事件分发机制以及滑动冲突的解决 声明:  本文主要涉及VIew的事件分发与滑动冲突的解决,关于View的事件分发流程的部分内容参考自:  Android事件分发机制详解:史上最全面.最 ...

  9. Android自定义view之事件传递机制

    Android自定义view之事件传递机制 在上一篇文章<Android自定义view之measure.layout.draw三大流程>中,我们探讨了一下view的显示过程.不太熟悉的同学 ...

最新文章

  1. 刚刚写了一个评星的脚本插件,分享给大家
  2. php路径设置,php进行数据库路径设置的方法
  3. Mule3用户手册:Mule ESB 3使用要点
  4. linux sdk 窗口句柄,Venus: 针对Linux平台上,对常用的系统API进行面向对象的封装SDK。...
  5. jQuery 1.4单独为某个动画动作设效果
  6. java调用Linux mahout,Mahout算法调用展示平台2.1
  7. 手把手教你利用微软的Bot Framework,LUIS,QnA Maker做一个简单的对话机器人
  8. 添加 centos 右键 terminal
  9. 通过人脸识别查找相似图片
  10. VS2010 中文版MSDN下载
  11. 《C程序员:从校园到职场》出版预告(3):从“阳春白雪”到“下里巴人”
  12. Python实现日周月排行榜
  13. 关于D3D9 Stretchrect
  14. MYSQL 命令行大全 (简洁、明了、全面)
  15. 外包干了三年,真废了。。。
  16. 高质量的博客该如何来进行打造?
  17. 2022 年超详细过程步骤讲解 CentOS 7 安装Maven。以及Mavne配置文件的修改
  18. 基本算术运算优先级(高到低)
  19. 蓝牙协议栈消息的关联
  20. Shell脚本中获取命令运行结果、特殊变量使用、条件判断等常用操作

热门文章

  1. 3小时快速入门数学建模竞赛-建模技巧2:追根溯源,站在巨人的肩膀上
  2. 《文明之光 第二册》一一16.1 寻找冯·布劳恩(1)
  3. 传感器,物联网时代的智能硬件数字化入口
  4. 阿里双十一大屏六年路
  5. LED显示屏公司如何在这个激烈的竟争中抓住机遇?
  6. STM32单片机智能跟随小车_红外遥控(程序+原理图+PCB+论文报告)
  7. python强制表白按钮-模仿抖音-新手勿喷
  8. about.php啥意思,about.php
  9. ChatGPT测评与感想:惊艳!它能完全理解你的问题
  10. key存在则更新,不存在则插入