• 再谈CLR:事件定义


    这是今天课堂上的一个话题。如何定义事件,这好像并不是问题,我们习惯性直接用下面的代码定义,不是吗?

        class Customer {
            public event EventHandler NameChanging;
    
        }

    这样做的话,大致是会怎么编译呢?

    image

    其实编译器会帮我们生成两个方法: add_NameChanging和remove_NameChanging

    还会有一个字段,是EventHandler这个类型的 。

    关键就在这里。它每次都会在创建对象的时候准备一个EventHandler,但问题是,并不是每个事件都会被用到。这就意味着,有一部分EventHandler其实是浪费的。

    如果类型的事件很多,那么这个问题可能比较明显。

    如何改进呢?

    请参考下面的代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel;
    
    
    namespace ConsoleApplication1
    {
        class Program
        {
    
            static void Main(string[] args)
            {
                Employee e = new Employee();
                e.NameEvent += new EventHandler(e_NameEvent);
                e.LNameEvent += new EventHandler(e_LNameEvent);
                e.Name = "ares";
                e.LName = "chen";
                Console.Read();
            }
    
            static void e_LNameEvent(object sender, EventArgs e)
            {
                Employee emp = (Employee)sender;
                Console.WriteLine(emp.LName);
            }
    
            static void e_NameEvent(object sender, EventArgs e)
            {
                Employee emp = (Employee)sender;
                Console.WriteLine(emp.Name);
            }
        }
    
        class Employee
        {
            private string name;
            public string Name
            {
                get
                {
                    return name;
                }
                set
                {
                    name = value;
                    
                    if (list[nameEventKey] != null)
                        list[nameEventKey].DynamicInvoke(new object[] { this, null });
                }
            }
    
    
            private string lname;
            public string LName
            {
                get
                {
                    return lname;
                }
                set
                {
                    lname = value;
    
                    if (list[lnameEventKey] != null)
                        list[lnameEventKey].DynamicInvoke(new object[] { this, null });
                }
            }
    
            private EventHandlerList list = new EventHandlerList();
    
            private object nameEventKey=null;
            public event EventHandler NameEvent
            {
                add
                {
                    if (nameEventKey == null)
                        nameEventKey = new object();
    
                    list.AddHandler(nameEventKey, value);
                }
                remove
                {
    
                    if (nameEventKey == null)
                        nameEventKey = new object();
                    list.RemoveHandler(nameEventKey, value);
                }
            }
    
            private object lnameEventKey=null;
            public event EventHandler LNameEvent
            {
                add
                {
                    if (lnameEventKey == null)
                        lnameEventKey = new object();
    
                    list.AddHandler(lnameEventKey, value);
                }
                remove
                {
                    if (lnameEventKey == null)
                        lnameEventKey = new object();
    
                    list.RemoveHandler(lnameEventKey, value);
                }
            }
        }
    }
    
  • 相关阅读:
    前端面试日更解答 interview-answe 1+1 2020-04-05
    Kafka学习系列----- 消费时序图
    JVM 垃圾回收算法简析
    ORM 框架选型对比
    Spring 中的设计模式之单例模式实现
    Synchroinzed 与lock 锁的区别
    Spring源码分析之ApplicationContextAware
    Springboot 启动简析
    HTTP/2.0 简单分析
    HTTPS 原理简要分析
  • 原文地址:https://www.cnblogs.com/chenxizhang/p/1691129.html
Copyright © 2020-2023  润新知