首页 > 其他分享 >通过反射获取事件Event并实现方法

通过反射获取事件Event并实现方法

时间:2023-10-26 18:34:24浏览次数:41  
标签:反射 Type timer method 获取 delegate type event Event

C# EventInfo.AddEventHandler方法代码示例

EventInfo.AddEventHandler(Object, Delegate) Method (System.Reflection) | Microsoft Learn

//引入命名空间
using System;
using System.Reflection;
using System.Reflection.Emit;

public class Example
{
    private static object timer;

    public static void Main()
    {
        // Get the Timer type.
        Type t = typeof(System.Timers.Timer);
        // Create an instance of the Timer type.
        timer = Activator.CreateInstance(t);

        // Use reflection to get the Elapsed event.
        EventInfo eInfo = t.GetEvent("Elapsed");

        // In order to create a method to handle the Elapsed event,
        // it is necessary to know the signature of the delegate 
        // used to raise the event. Reflection.Emit can then be
        // used to construct a dynamic class with a static method
        // that has the correct signature.
 
        // Get the event handler type of the Elapsed event. This is
        // a delegate type, so it has an Invoke method that has
        // the same signature as the delegate. The following code
        // creates an array of Type objects that represent the 
        // parameter types of the Invoke method.
        //
        Type handlerType = eInfo.EventHandlerType;
        MethodInfo invokeMethod = handlerType.GetMethod("Invoke");
        ParameterInfo[] parms = invokeMethod.GetParameters();
        Type[] parmTypes = new Type[parms.Length];
        for (int i = 0; i < parms.Length; i++)
        {
            parmTypes[i] = parms[i].ParameterType;
        }

        // Use Reflection.Emit to create a dynamic assembly that
        // will be run but not saved. An assembly must have at 
        // least one module, which in this case contains a single
        // type. The only purpose of this type is to contain the 
        // event handler method. (You can use also dynamic methods, 
        // which are simpler because there is no need to create an 
        // assembly, module, or type.)
        //
        AssemblyName aName = new AssemblyName();
        aName.Name = "DynamicTypes";
        AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run);
        ModuleBuilder mb = ab.DefineDynamicModule(aName.Name);
        TypeBuilder tb = mb.DefineType("Handler", TypeAttributes.Class | TypeAttributes.Public);

        // Create the method that will handle the event. The name
        // is not important. The method is static, because there is
        // no reason to create an instance of the dynamic type.
        //
        // The parameter types and return type of the method are
        // the same as those of the delegate's Invoke method, 
        // captured earlier.
        MethodBuilder handler = tb.DefineMethod("DynamicHandler", 
            MethodAttributes.Public | MethodAttributes.Static, 
            invokeMethod.ReturnType, parmTypes);

        // Generate code to handle the event. In this case, the 
        // handler simply prints a text string to the console.
        //
        ILGenerator il = handler.GetILGenerator();
        il.EmitWriteLine("Timer's Elapsed event is raised.");
        il.Emit(OpCodes.Ret);

        // CreateType must be called before the Handler type can
        // be used. In order to create the delegate that will
        // handle the event, a MethodInfo from the finished type
        // is required.
        Type finished = tb.CreateType();
        MethodInfo eventHandler = finished.GetMethod("DynamicHandler");

        // Use the MethodInfo to create a delegate of the correct 
        // type, and call the AddEventHandler method to hook up 
        // the event.
        Delegate d = Delegate.CreateDelegate(handlerType, eventHandler);
        eInfo.AddEventHandler(timer, d);

        // Late-bound calls to the Interval and Enabled property 
        // are required to enable the timer with a one-second
        // interval.
        t.InvokeMember("Interval", BindingFlags.SetProperty, null, timer, new Object[] { 1000 });
        t.InvokeMember("Enabled", BindingFlags.SetProperty, null, timer, new Object[] { true });

        Console.WriteLine("Press the Enter key to end the program.");
        Console.ReadLine();
    }
}

 

标签:反射,Type,timer,method,获取,delegate,type,event,Event
From: https://www.cnblogs.com/MarcLiu/p/17790078.html

相关文章

  • golang 获取 mongo 数据库状态
    命令行模式navicatgolangpackagemainimport( "context" "encoding/json" "fmt" "log" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-drive......
  • java如何从Content-Disposition获取文件名的正则表达式
    一,主要是关于:post请求下载文件,如何从Content-Disposition获取文件名的正则表达式记录:HttpResponsehttpResponse=httpRequest.execute();byte[]bytes=httpResponse.bodyBytes();Stringheader=httpResponse.header("Content-Disposition")......
  • Java Calendar类练习题(获取日期)
    1.获取当前对象的日期的100天前的日期packagezuoye;importjava.text.SimpleDateFormat;importjava.util.Calendar;importjava.util.Date;publicclassTest1_01{publicstaticvoidmain(String[]args){//1、获取当前对象的日期的100天前的日期Calendarc......
  • Qt开发之获取文件元数据的信息
    效果展示:源码如下:头文件(.h)#ifndefMAINWINDOW_H#defineMAINWINDOW_H#include<QWidget>#include<QLabel>#include<QLineEdit>#include<QPushButton>#include<QCheckBox>#include<QHBoxLayout>#include<QVBoxLayout>......
  • C# event随笔
    通过事件使用委托        事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。包含事件的类用于发布事件。这被称为 发布器(publisher) 类。其他接受该事件的类被称为 订阅器(subscriber) 类。事件使用 发布-订阅(publisher-subscriber) 模型。......
  • cpp以毫秒级精度获取当前时刻的时间戳
    首先获得当前时刻的时间点std::chrono::time_point<std::chrono::system_clock,std::chrono::milliseconds>   tp=std::chrono::time_point_cast<std::chrono::milliseconds>(     std::chrono::system_clock::now());再将时间点转换为时间戳形式inttim......
  • EventLoop(事件循环)
    EventLoop(事件循环)一、前言JS任务分为同步任务(非耗时任务)和异步任务(耗时任务),异步任务又分为宏任务和微任务。eventloop:JS主线程不断的循环往复的从任务队列中读取任务,执⾏任务,这种运⾏机制称为事件循环(eventloop)二、同步和异步​ JS是单线程执行的语言,在同一个时间......
  • 获取 el-cascader 的输入值
    问题场景使用el-cascader级联选择器时,设置filterable可搜索选项。但怎样获取输入框的输入值呢?解决官方文档给出了如下事件:其中change事件获取到的是选中的选项的值,如果输入值不符合选项值(即没有选中),则无法获取输入值。那么为了获取到输入值,就只有用blur事件,即失去焦......
  • linux获取文件或者是进程精确时间的方法
    linux获取文件或者是进程精确时间的方法背景很多时候需要精确知道文件的具体时间.也需要知道进程的开始的精确时间.便于进行一些计算的处理.其实linux里面有很多方式进行文件属性的查看.这里简单总结一下.文件系统时间查看ls以及ll命令可以查看文件的一些简要信息但......
  • 获取共享网络的内网IP
     本人有一个iPad,上网用的是电脑共享的网络。  是通过USA连接的共享的方式,结果就不知道iPad的IP了, iPad也没有越狱。被这个问题居然犯难了。 想到用arp广播一下,肯定会有回复。从当前IP地址中寻找。 因为是USA共享,肯定是桥接方式,找 尾部是[bridge]的。......