在真实的项目中,有的对象有相当多的事件,例如一个窗体就有好多种事件。默认情况下,当声明事件时,编译器将内存分配给一个事件字段,一存储事件信息。如果类中有好多事件未使用,则他们会不必要的占用内存。

这种情况下,.NETFramework提供了EventHandlerList类来减少内存的占用。它可以被看作事件的集合,只有需要响应的事件才拥有方法调用列表,才会在EventHandlerList对象中出现。

EventHandlerList:

为了节省内存而设计的。
当你定义一个事件的时候,通常也要定义相应的委托,在初始化的时候,就会为所有事件、委托分配内存空间。
但如果有许多未被使用到的事件,那么这些空间就浪费了。
EventHandlerList是专门用于保存委托的线性表,它存储的是Delegate类型,所有委托的基类,也就是任意委托都可存储。
可以看到无论是Form,还是HttpAppliaction类,都有定义一个EventHandlerList类型的Events属性,用于存储所有事件委托

如果用EventHandlerList对象来保存事件的相应方法,必须为每一个事件编写特殊的访问器:

class MyControl1
{
    // 即使没有订阅,每个事件作为类成员需要4个字节(的引用,没有订阅时为null)。
    // Winform的控件至少有70个事件, 这就要280个字节,且大部分事件都没有被用到。
    // 就是说每个UI上的控件,Lable,Button,TextBox,等等,每个都可能浪费约300个字节。
    public event EventHandler Initializing;
    public event EventHandler Initialized;
    // ...
    public event EventHandler MouseDown;
    public event EventHandler MouseUp;
    public event EventHandler MouseMove;
    public event EventHandler MouseClick;
    public event EventHandler MouseDoubleClick;
    public event EventHandler KeyDown;
    public event EventHandler KeyUp;
    // ...
}
 
class MyControl2
{
    // 一个EventHandlerList初始只要4个字节(的引用)
    private EventHandlerList _events;
    protected EventHandlerList Events
    {
        get 
        
            if (_events == null) _events = new EventHandlerList();
            return _events;
        }
    }
 
    public event EventHandler Initializing
    {
        add { Events.AddHandler("Initializing", value); }  // 按需增加
        remove { Events.RemoveHandler("Initializing", value); }
    }
 
    public event EventHandler Initialized
    {
        add { Events.AddHandler("Initialized", value); }
        remove { Events.RemoveHandler("Initialized", value); }
    }
}
说明:只有在事件很多的情况下需要,本身事件不多的控件,没有必要设置事件访问器
 
 
一般的事件也可以写事件访问器,如果不写,也不会有什么影响,因为.net会自动生成,对于lock,在4.0以后没有什么意义,.net已经优化了访问过程。
特此在这说明是为了我们看一些老的代码的时候,能够理解是在做什么。
    public class Shape : IDrawingObject, IShape  

{  // Create an event for each interface event

    event EventHandler PreDrawEvent;

    event EventHandler PostDrawEvent;

    object objectLock = new Object();

    event EventHandler IDrawingObject.OnDraw

{

add

{  lock (objectLock)

{

PreDrawEvent += value;

}

}

remove

{

    lock (objectLock)

{

PreDrawEvent -= value;

}

}

}

C#事件の事件访问器的更多相关文章

  1. 编写高质量代码改善C#程序的157个建议——建议151:使用事件访问器替换公开的事件成员变量

    建议151:使用事件访问器替换公开的事件成员变量 事件访问器包含两部分内容:添加访问器和删除访问器.如果涉及公开的事件字段,应该始终使用事件访问器.代码如下所示: class SampleClass ...

  2. JavaScript DOM高级程序设计 4.3控制事件流和注册事件侦听器--我要坚持到底!

    一.事件流 我们通过下面一个实例,进行说明. <body> <h1>Event Flow</h1> <ul id="nav"> &l ...

  3. js事件流、事件处理程序/事件侦听器

    1.事件流 事件冒泡 IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档). 事件捕获 ...

  4. javascript中事件总结&通用的事件侦听器函数封装&事件委托

    前言: JAVASCRIPT与HTML之间的交互是通过事件来实现的.事件,就是文档或浏览器窗口中发生的一些特定交互瞬间.可以使用侦听器( 或处理程序 )来预定事件,以便事件发生时执行相应的代码.这种在 ...

  5. 052_末晨曦Vue技术_处理边界情况之程序化的事件侦听器

    程序化的事件侦听器 点击打开视频讲解更详细 现在,你已经知道了 $emit 的用法,它可以被 v-on 侦听,但是 Vue 实例同时在其事件接口中提供了其它的方法.我们可以: 通过 $on(event ...

  6. Android事件侦听器回调方法浅谈

    http://developer.51cto.com/art/201001/180846.htm Android事件侦听器作为视图View类的接口,其中包含有不少回调方法,比如:onClick():o ...

  7. Yarn源码分析之事件异步分发器AsyncDispatcher

    AsyncDispatcher是Yarn中事件异步分发器,它是ResourceManager中的一个基于阻塞队列的分发或者调度事件的组件,其在一个特定的单线程中分派事件,交给AsyncDispatch ...

  8. C#属性访问器

    属性的访问器包含与获取或设置属性有关的可执行语句.访问器声明可以包含 get 访问器或 set 访问器,或者两者均包含.声明采用下列形式之一:get {}set {} get 访问器get 访问器体与 ...

  9. 【温故而知新-万花筒】C# 异步编程 逆变 协变 委托 事件 事件参数 迭代 线程、多线程、线程池、后台线程

    额基本脱离了2.0 3.5的时代了.在.net 4.0+ 时代.一切都是辣么简单! 参考文档: http://www.cnblogs.com/linzheng/archive/2012/04/11/2 ...

随机推荐

  1. 爬虫之re数据提取的使用

    本文将业务场景中最常用的几点实例,给大家列举出来,不常见的不再一一赘述.  使用urllib库可以模拟浏览器发送请求获得服务器返回的数据,下一步就是把有用的数据提取出来.数据分为两种形式:结构化和非结 ...

  2. js 的运算

    1.parselnt() 2.parsefloat() 遇到第一个字节是非数字就结束了. 3.var a="hello world" a 这个变量是字符串了,对于里面每一个字母来说 ...

  3. Mybatis框架基础支持层——反射工具箱之Reflector&ReflectorFactory(3)

    说明:Reflector是Mybatis反射工具的基础,每个Reflector对应一个类,在Reflector中封装有该类的元信息, 以及基于类信息的一系列反射应用封装API public class ...

  4. Python全栈开发之---输入输出与流程控制

    Python简介 python是吉多·范罗苏姆发明的一种面向对象的脚本语言,可能有些人不知道面向对象和脚本具体是什么意思,但是对于一个初学者来说,现在并不需要明白.大家都知道,当下全栈工程师的概念很火 ...

  5. Go开发之路 -- strings以及strconv的使用

    strings的使用 HasPrefix 语法: strings.HasPrefix(s, prefix string) bool // 判断字符串s是否以prefix开头 // 判断一个url是否以 ...

  6. express 连接数据库

    (1)创建项目 ,项目名cntMongodb express -e cntMongodbcd cntMonfodbnpm installnpm install mongoose --save //安装 ...

  7. CentOS 7.0 下 Python 2.7 升级到 Python 3.5

    前段因为时间工作需要,要把 Centos 7.0 默认安装的 Python 2.7 升级到 Python 3.5. 具体操作如下: # 安装 gcc gcc-c++ 等编译工具软件 yum insta ...

  8. 2018-09-28 用Python3和tkinter开发简单图形界面程序

    源码库: program-in-chinese/wubi_code_editor 起因在这里. 由于此项目和汉字相关, 个人也想尝试Python的图形界面开发, 于是开始尝试. 遇到的一个坑. 用户测 ...

  9. 如何理解MVC?

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范. 那么MVC框架究竟干了些什么:用一种业务逻辑. ...

  10. 华为P20无线投屏到电脑 绝地求生投射电脑

    如今出门在外,必不可少的就是手机,如果没有了手机,每个人都会感觉没有安全感,感觉和世界失去了联系,我们每天每个人都在使用手机,但是作为华为手机用户的你,了解华为P20无线投屏到电脑是怎么操作的吗? 使 ...