zoukankan      html  css  js  c++  java
  • C#事件の事件访问器

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

    这种情况下,.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;  

                    }  

                }  

            }

  • 相关阅读:
    jQuery 自执行函数
    IRelationalOperator空间关系接口简介
    9.2 空间拓扑运算[转]
    解决关于ArcGIS10.2服务手动启动的问题
    Multipart to single part feature
    Multipart polyline to single part lines
    VS2015 C#6.0 中的没有实现/支持的特性
    VS2015 C#6.0 中的那些新特性
    ArcGIS中各种合并要素(Union、Merge、Append、Dissolve)的异同点分析 转载
    FME2010 案例分析: 动态批量转换
  • 原文地址:https://www.cnblogs.com/xietianjiao/p/7508873.html
Copyright © 2011-2022 走看看