• CodeDom系列事件(event)定义和反射调用


        CodeDom提供了对事件的支持,以及我们可以用反射机制对CodeDom生成的事件进行注册,以及调用。本节程序很简单,先贴上我将用CodeDom生成的代码:

    namespace CodeDomDemo3
    {
    using System;
    public class CodeDomDemo3
    {
    public event System.EventHandler MyEvent;
    protected virtual void OnHandle(System.EventArgs e)
    {
    if ((this.MyEvent != null))
    {
    this.MyEvent(this, e);
    }
    }
    public void CallEvent()
    {
    this.OnHandle(EventArgs.Empty);
    }
    }
    }

    代码很简单哦,主要是看CodeDom的事件定义机制和反射调用CodeDom编译的类型方法事件。

    CodeDom代码为:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.CodeDom;
    namespace CodeDomDemo1
    {
    public class CodeDomDemo3
    {
    public CodeNamespace CreateCodeNamespcae()
    {
    CodeNamespace nspcae = new CodeNamespace("CodeDomDemo3");
    nspcae.Imports.Add(new CodeNamespaceImport("System"));
    nspcae.Types.Add(CrateClassType());
    return nspcae;
    }
    public CodeTypeDeclaration CrateClassType()
    {
    //field event
    CodeMemberEvent myevent = new CodeMemberEvent();
    myevent.Attributes = MemberAttributes.Public;
    myevent.Type = new CodeTypeReference(typeof(EventHandler));
    myevent.Name = "MyEvent";
    // event method OnHandle;
    CodeMemberMethod method = new CodeMemberMethod();
    method.Name = "OnHandle";
    method.Attributes = MemberAttributes.Family;
    method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(EventArgs)), "e"));
    method.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeEventReferenceExpression(
    new CodeThisReferenceExpression(),"MyEvent"),
    CodeBinaryOperatorType.IdentityInequality,new CodePrimitiveExpression(null)),
    new CodeExpressionStatement(new CodeDelegateInvokeExpression(new CodeEventReferenceExpression(
    new CodeThisReferenceExpression(),
    "MyEvent"), new CodeExpression[] { new CodeThisReferenceExpression(), new CodeArgumentReferenceExpression("e"),
    }))));
    CodeMemberMethod callEvent = new CodeMemberMethod();
    callEvent.Name = "CallEvent";
    callEvent.Attributes = MemberAttributes.Public | MemberAttributes.Final;
    callEvent.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "OnHandle", new CodeExpression[]
     {new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("EventArgs"),"Empty") }));
    CodeTypeDeclaration myclass = new CodeTypeDeclaration("CodeDomDemo3");
    myclass.Attributes = MemberAttributes.Public;
    myclass.Members.AddRange(new CodeTypeMember[] { myevent, method, callEvent });
    return myclass;
    }
    }
    }
    1:主要注意委托的调用:
    public CodeDelegateInvokeExpression(
    CodeExpression targetObject,//事件的引用
    CodeExpression[] parameters//参数
    )
    2:事件的添加(+=):
    public CodeAttachEventStatement(
    CodeExpression targetObject,//目标对象
    string eventName,//事件名
    CodeExpression listener//监听者
    )
    3:事件的移除(-=):
    public CodeRemoveEventStatement(
    CodeExpression targetObject,//目标对象
    string eventName,//事件名
    CodeExpression listener//监听者
    )
       利用反射调用事件代码:
    Type t = result.CompiledAssembly.GetType("CodeDomDemo3.CodeDomDemo3");//获取类型
    object obj= Activator.CreateInstance(t);//创建实例
    t.GetEvent("MyEvent").AddEventHandler(obj, new EventHandler(pro.CallEvent));//添加事件
    t.GetMethod("CallEvent").Invoke(obj, null);//触发事件
    本示例代码下载:CodeDomDemo3


    作者:破  狼
    出处:http://www.cnblogs.com/whitewolf/
    本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客博客园--破狼51CTO--破狼

  • 相关阅读:
    VSCode的终端修改
    vim总结
    分布式的CAP理论
    MongoDB常用命令总结
    nginx负载均衡总结
    【重要】nginx location配置和rewrite写法
    Linux四剑客find/grep/awk/sed
    IDEA插件开发总结
    支付宝在线支付接口开发流程
    Centos7 网卡Device does not seem to be present解决办法
  • 原文地址:https://www.cnblogs.com/whitewolf/p/1762589.html
Copyright © 2020-2023  润新知