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

这种情况下,.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. SQL去除数据库表中tab、空格、回车符等特殊字符的解决方法

    按照ASCII码, SELECT char(64) 例如64 对应 @,则 ), 'kk'); 则结果为 abckkqq.com 依此类推, 去掉其他特殊符号,参考ASCII码对照表, 去掉tab符号 ...

  2. .NET面试题01-值类型与引用类型

    常见面试题目: 1. 值类型和引用类型的区别? 2. 结构和类的区别? 3. delegate是引用类型还是值类型?enum.int[]和string呢? 4. 堆和栈的区别? 5. 什么情况下会在堆 ...

  3. [android] 保存联系人到系统通讯录

    对应着读联系人,把数据写进去,市场上的社交类应用经常会有这样的功能 向raw_contacts表中添加一个id 向data表里面添加对应的数据 获取ContentResolver对象,通过getCon ...

  4. 谈谈mysql的悲观和乐观锁

    悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.之前有写过一篇文章关于并发的处理思路和解决方案,这里我单独将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍一 ...

  5. 【Zookeeper】windows环境下zookeeper安装

    下载  Apache官方最新版本为:3.4.12 下载地址:https://mirrors.cnnic.cn/apache/zookeeper/zookeeper-3.4.12/ 安装 解压到指定目录 ...

  6. 为链表数据结构实现iterator接口

    iterator作用 为所有的数据结构提供统一的访问方式. 接口对象 接口对象一共有3个方法,next()方法.return()方法.throw()方法. next() 必填 用于for..of迭代. ...

  7. blfs(systemd版本)学习笔记-编译安装配置dhcpcd

    我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! dhcpcd项目地址:http://www.linuxfromscratch.org/blfs/view/stable-syst ...

  8. JavaScript String常用方法和属性

    在JavaScript中,字符串是不可变的,如果使用索引对字符串进行修改浏览器不会报错,但也没有任何效果.JavaScript提供的这些方法不会修改原有字符串的内容,而是返回一个新的期望的字符串. 一 ...

  9. elementUI vue v-model的修饰符

    v-model的修饰符 v-model.lazy 只有在input输入框发生一个blur时才触发 v-model.trim 将用户输入的前后的空格去掉 v-model.number 将用户输入的字符串 ...

  10. Dynamics 365工作流报错:您无法登陆系统。原因可能是您的用户记录或您所属的业务部门在Microsoft Dynamics 365中已被禁用。

    本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复265或者20170926可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me ...