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

这种情况下,.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. .NET页面导出Excel

    public static void CreateExcel(DataSet ds)        {            string filename = DateTime.Now.ToStri ...

  2. nginx配置反向代理和负载均衡

    一.反向代理 说明:应该有一个nginx服务器有多个应用服务器(可以是tomcat),本文使用一台虚拟机,安装一个nginx,多个tomcat,来模拟 upstream tomcats{ server ...

  3. 【Java每日一题】20170329

    20170328问题解析请点击今日问题下方的“[Java每日一题]20170329”查看(问题解析在公众号首发,公众号ID:weknow619) package Mar2017; public cla ...

  4. 递归 + OS模块

    ''' 递归调用 :一个函数,调用了自身,称为递归调用 递归函数:一个会调用自身的函数称为递归函数 凡是循环能干的事,递归都能干 ''' ''' 方式: 1.写出临界条件 2.找这一次和上一次的关系 ...

  5. CSS3效果:5种预载动画效果

    实现如图所示的动画效果: 预载动画一:双旋圈 在两个不同方向旋转的圆圈.我们对内圈的转速定义了一个CSS代码,即内圈比外圈的速率快2倍.实现如图所示: html代码: <body style=& ...

  6. cf932E. Team Work(第二类斯特灵数 组合数)

    题意 题目链接 Sol 这篇题解写的非常详细 首先要知道第二类斯特灵数的一个性质 \[m^n = \sum_{i = 0}^m C_{n}^i S(n, i) i!\] 证明可以考虑组合意义:\(m^ ...

  7. Java synchronized 线程同步

    同步方法 class MyTheard4 implements Runnable{ private int ticket; public MyTheard4(int ticket) { this.ti ...

  8. Android调用系统图库返回路径

    调用系统图库: Intent intent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI); ...

  9. C# Json.Net解析实例

    本文以一个简单的小例子,简述Json.Net的相关知识,仅供学习分享使用,如有不足之处,还请指正. 概述 Json.Net is a Popular high-performance JSON fra ...

  10. JNI C反射调用java方法

    前面记录了调用C的学习笔记,现在来记录一下C反射调用Java的笔记.JNI开发学习之调用C方法 Android开发中调用一个类中没有公开的方法,可以进行反射调用,而JNI开发中C调用java的方法也是 ...