『.Net反射』ILGenerator.Emit 动态MSIL 编程 入门

转载请标明:舒小龙 http://www.cnblogs.com/shuxiaolong/articles/2924574.html

什么都不说,直接贴代码:

 1     class Program  2  {  3         static void Main(string[] args)  4  {  5  SetValue();  6  }  7 
 8         public static void SetValue()  9  { 10             int temp1 = 123; 11             int temp2 = 234; 12             int sum = temp1 + temp2; 13             string sumStr = sum.ToString(); 14 
15  Console.WriteLine(sumStr); 16  } 17     }

对应的 ILGenerator.Emit 代码:

 1  class Program  2  {  3         static void Main(string[] args)  4  {  5 //.method public hidebysig static void SetValue() cil managed  6 //{  7 //  // 代码大小 30 (0x1e)  8 // .maxstack 2  9 // .locals init ([0] int32 temp1,  10 // [1] int32 temp2,  11 // [2] int32 sum,  12 // [3] string sumStr)  13 // IL_0000: nop  14 // IL_0001: ldc.i4.s 123  15 // IL_0003: stloc.0  16 // IL_0004: ldc.i4 0xea  17 // IL_0009: stloc.1  18 // IL_000a: ldloc.0  19 // IL_000b: ldloc.1  20 // IL_000c: add  21 // IL_000d: stloc.2  22 // IL_000e: ldloca.s sum  23 // IL_0010: call instance string [mscorlib]System.Int32::ToString()  24 // IL_0015: stloc.3  25 // IL_0016: ldloc.3  26 // IL_0017: call void [mscorlib]System.Console::WriteLine(string)  27 // IL_001c: nop  28 // IL_001d: ret  29 //} // end of method Program::SetValue
 30  SetValue();  31  }  32 
 33         public static void SetValue()  34  {  35             DynamicMethod dm = new DynamicMethod("SetValueMethod", null, new Type[] { /*typeof(object), typeof(object)*/ }, true);  36 
 37             ILGenerator generator = dm.GetILGenerator();  38 
 39             generator.DeclareLocal(typeof(int));    //声明变量
 40             generator.DeclareLocal(typeof(int));    //声明变量
 41             generator.DeclareLocal(typeof(int));    //声明变量
 42             generator.DeclareLocal(typeof(string));    //声明变量  43 
 44             //加载参数1,需要注意的是静态方法Ldarg_0对应的是参数1,  45             //实例方法Ldarg_0对应的是this指针,Ldarg_1对应的是参数1,  46             //即每个实例方法都传递一个隐含的this指针  47 
 48             //int temp1 = 123;  49             //int temp2 = 234;  50             //int sum = temp1 + temp2;  51             //string sumStr = sum.ToString();  52             //Console.WriteLine(sumStr);  53 
 54             //temp1 = 123
 55             generator.Emit(OpCodes.Ldc_I4, 123);  56  generator.Emit(OpCodes.Stloc_0);  57 
 58             //temp2 = 234
 59             generator.Emit(OpCodes.Ldc_I4, 234);  60  generator.Emit(OpCodes.Stloc_1);  61 
 62             //sum = temp1 + temp2
 63  generator.Emit(OpCodes.Ldloc_0);  64  generator.Emit(OpCodes.Ldloc_1);  65  generator.Emit(OpCodes.Add);  66  generator.Emit(OpCodes.Stloc_2);  67 
 68             //string sumStr = sum.ToString();  69             //ldloca.s sum  70             //call instance string [mscorlib]System.Int32::ToString()  71             //stloc.3  72             //调用成员函数
 73             generator.Emit(OpCodes.Ldloca_S, 2); //generator.Emit(OpCodes.Ldloc_2);
 74             MethodInfo toStringMethodInfo = typeof(Int32).GetMethod("ToString", new Type[] { });  75  generator.Emit(OpCodes.Call, toStringMethodInfo);  76             //generator.EmitCall(OpCodes.Call, toStringMethodInfo, null); //和上面代码 同意思
 77  generator.Emit(OpCodes.Stloc_3);  78 
 79             //Console.WriteLine(sumStr);  80             //IL_0016: ldloc.3  81             //IL_0017: call void [mscorlib]System.Console::WriteLine(string)  82             //调用静态函数
 83  generator.Emit(OpCodes.Ldloc_3);  84             MethodInfo writeLineMethodInfo = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });  85  generator.Emit(OpCodes.Call, writeLineMethodInfo);  86             //generator.EmitCall(OpCodes.Call, writeLineMethodInfo, null); //和上面代码 同意思  87 
 88             //generator.Emit(OpCodes.Pop); //是否是 无返回值函数 调用之后,不用弹出堆栈?  89 
 90             //return
 91             generator.Emit(OpCodes.Ret);   //函数执行完成  92 
 93             
 94 
 95 
 96             //将函数作为 委托
 97             VoidNoParamsMethod delegateMethod = (VoidNoParamsMethod)dm.CreateDelegate(typeof(VoidNoParamsMethod));  98             //执行委托
 99  delegateMethod.Invoke(); 100  } 101 
102 
103         public delegate void VoidNoParamsMethod(); 104     }

--------------------------------------------------------------------------

 1 class Program  2  {  3         static void Main(string[] args)  4  {  5             TestClass testClass = new TestClass();  6             testClass.Age = 1234;  7             int age = testClass.Age;  8  Console.WriteLine(age);  9  } 10 
11 
12          
13  } 14 
15     public class TestClass 16  { 17         public int Age; 18     }

对应的 ILGenerator.Emit 代码:

 1 class Program  2  {  3         static void Main(string[] args)  4  {  5 //.method private hidebysig static void Main(string[] args) cil managed  6 //{  7 // .entrypoint  8 //  // 代码大小 33 (0x21)  9 // .maxstack 2 10 // .locals init ([0] class ComplexSetValue.TestClass testClass, 11 // [1] int32 age) 12 // IL_0000: nop 13 // IL_0001: newobj instance void ComplexSetValue.TestClass::.ctor() 14 // IL_0006: stloc.0 15 // IL_0007: ldloc.0 16 // IL_0008: ldc.i4 0x4d2 17 // IL_000d: stfld int32 ComplexSetValue.TestClass::Age 18 // IL_0012: ldloc.0 19 // IL_0013: ldfld int32 ComplexSetValue.TestClass::Age 20 // IL_0018: stloc.1 21 // IL_0019: ldloc.1 22 // IL_001a: call void [mscorlib]System.Console::WriteLine(int32) 23 // IL_001f: nop 24 // IL_0020: ret 25 //} // end of method Program::Main
26 
27             DynamicMethod dm = new DynamicMethod("SetValueMethod", null, new Type[] { /*typeof(object), typeof(object)*/ }, true); 28 
29             ILGenerator generator = dm.GetILGenerator(); 30 
31             generator.DeclareLocal(typeof(TestClass));  //声明变量
32             generator.DeclareLocal(typeof(int));  //声明变量 33 
34             //加载参数1,需要注意的是静态方法Ldarg_0对应的是参数1, 35             //实例方法Ldarg_0对应的是this指针,Ldarg_1对应的是参数1, 36             //即每个实例方法都传递一个隐含的this指针 37 
38             //TestClass testClass = new TestClass(); 39             //testClass.Age = 1234; 40             //int age = testClass.Age; 41             //Console.WriteLine(age); 42 
43             //TestClass testClass = new TestClass(); 44             //newobj instance void ComplexSetValue.TestClass::.ctor()
45             ConstructorInfo testClassConstructor = typeof (TestClass).GetConstructor(new Type[] {}); 46  generator.Emit(OpCodes.Newobj, testClassConstructor); 47  generator.Emit(OpCodes.Stloc_0); 48 
49             //testClass.Age = 1234; 50             //ldloc.0 51             //ldc.i4 0x4d2 //1234 52             //stfld int32 ComplexSetValue.TestClass::Age
53  generator.Emit(OpCodes.Ldloc_0); 54             generator.Emit(OpCodes.Ldc_I4, 1234); 55             FieldInfo fieldInfo = typeof (TestClass).GetField("Age"); 56  generator.Emit(OpCodes.Stfld, fieldInfo); 57 
58             //int age = testClass.Age; 59             //ldloc.0 60             //ldfld int32 ComplexSetValue.TestClass::Age 61             //stloc.1
62  generator.Emit(OpCodes.Ldloc_0); 63  generator.Emit(OpCodes.Ldfld, fieldInfo); 64  generator.Emit(OpCodes.Stloc_1); 65 
66             //Console.WriteLine(age); 67             //ldloc.0 68             //call void [mscorlib]System.Console::WriteLine(object)
69  generator.Emit(OpCodes.Ldloc_1); 70             MethodInfo writeLineMethodInfo = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }); 71  generator.Emit(OpCodes.Call, writeLineMethodInfo); 72             //generator.EmitCall(OpCodes.Call, writeLineMethodInfo, null); //和上面代码 同意思 73 
74             //generator.Emit(OpCodes.Pop); //是否是 无返回值函数 调用之后,不用弹出堆栈? 75 
76             //return
77             generator.Emit(OpCodes.Ret);   //函数执行完成 78 
79 
80             //将函数作为 委托
81             VoidNoParamsMethod delegateMethod = (VoidNoParamsMethod)dm.CreateDelegate(typeof(VoidNoParamsMethod)); 82             //执行委托
83  delegateMethod.Invoke(); 84  } 85  } 86 
87     public delegate void VoidNoParamsMethod(); 88 
89     public class TestClass 90  { 91         public int Age; 92     }

 

你可能感兴趣的:(generator)