使用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
原文地址:https://www.cnblogs.com/evlon/p/1623025.html