zoukankan      html  css  js  c++  java
  • 使用Emit动态调用方法(技术原型)

        上周五快下班时,看到一个博友BillGan文章:DynamicMethod (JIT Compiler encountered an internal limitation. )我还是相信中国人 ,当时没有太多时间,只是实现了调用静态方法的访问,不能称为动态方法调用。今天看到,BillGan好像已经死心了。

         不过,其实没有那么绝望的吧,我实现了一个原型,原理是使用Emit声明一个变量,然后强制类型转化成类型,最后再去调用方法:

    代码
    1 using System;
    2  using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5 using System.Reflection.Emit;
    6 using System.Reflection;
    7 using Evlon.Util.Dynamic;
    8
    9 namespace ConsoleApplication2008
    10 {
    11 public class Program
    12 {
    13 static void Main(string[] args)
    14 {
    15 decimal ret = new Program().Dynamic("HelloWorld", Guid.NewGuid(), 2009);
    16 Console.WriteLine(ret);
    17
    18 Console.ReadLine();
    19 }
    20
    21 public decimal HelloWorld(Guid userId, int year)
    22 {
    23 return userId.GetHashCode() + year;
    24 }
    25 }
    26
    27 }
    28 namespace Evlon.Util.Dynamic
    29 {
    30 public static class TypeExtension
    31 {
    32 public static decimal Dynamic(this object inst, string methodName, Guid userId, int year)
    33 {
    34 Type instType = inst.GetType();
    35 Type[] paramTypes = new Type[] { typeof(object), typeof(Guid), typeof(int) };
    36 Type[] paramMethodTypes = new Type[] { typeof(Guid), typeof(int) };
    37 var dynamicMethod = new DynamicMethod("", typeof(decimal), paramTypes, true);
    38 MethodInfo stringMethod = inst.GetType().GetMethod(methodName, paramMethodTypes);
    39
    40 var ilGen = dynamicMethod.GetILGenerator();//IL生成器
    41
    42 //声明变量
    43 ilGen.DeclareLocal(instType);
    44
    45
    46 //把参数推到堆栈上
    47 ilGen.Emit(OpCodes.Ldarg_0);
    48
    49 //把参数1转化成指定的类型
    50 ilGen.Emit(OpCodes.Castclass, instType);
    51 ilGen.Emit(OpCodes.Stloc_0);
    52
    53 //加载参数
    54 ilGen.Emit(OpCodes.Ldloc_0);
    55 ilGen.Emit(OpCodes.Ldarg_1);
    56 ilGen.Emit(OpCodes.Ldarg_2);
    57
    58 //调用方法
    59 ilGen.Emit(OpCodes.Callvirt, stringMethod);
    60 ilGen.Emit(OpCodes.Ret);//结束并返回值
    61
    62 //生成委托
    63 Func<object, Guid, int, decimal> gan = (Func<object, Guid, int, decimal>)dynamicMethod.CreateDelegate(typeof(Func<object, Guid, int, decimal>));
    64
    65 //调用委托返回结果
    66 return gan(inst, userId, year);
    67 }
    68
    69 }
    70 }
    71
  • 相关阅读:
    如何分配资源和管理资源
    让Project把周六和周日也计算工期
    Project设置子任务
    pytest-配置文件
    pytest-fixture
    pytest-标记
    pytest-断言
    pytest-参数化
    pytest入门
    maven-插件
  • 原文地址:https://www.cnblogs.com/evlon/p/1623025.html
Copyright © 2011-2022 走看看