高性能反射初体验3

动态生成View Code
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Reflection;
  6 using System.Reflection.Emit;
  7 using System.Threading;
  8 
  9 namespace Reflx_Method
 10 {
 11     public class Class1
 12     {
 13         public Class1()
 14         { }
 15         /// <summary>
 16         /// 
 17         /// </summary>
 18         public void CreateDynamicType()
 19         {
 20             Type[] ctorParams = new Type[] {typeof(int),
 21                    typeof(int)};
 22 
 23             AppDomain myDomain = Thread.GetDomain();
 24             AssemblyName myAsmName = new AssemblyName();
 25             myAsmName.Name = "MyDynamicAssembly";
 26 
 27             AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
 28                            myAsmName,
 29                            AssemblyBuilderAccess.RunAndSave);
 30 
 31             ModuleBuilder pointModule = myAsmBuilder.DefineDynamicModule("PointModule",
 32                                          "Point.dll");
 33 
 34             TypeBuilder pointTypeBld = pointModule.DefineType("Point1",
 35                                        TypeAttributes.Public);
 36 
 37             FieldBuilder xField = pointTypeBld.DefineField("x", typeof(int),
 38                                                            FieldAttributes.Public);
 39             FieldBuilder yField = pointTypeBld.DefineField("y", typeof(int),
 40                                                            FieldAttributes.Public);
 41 
 42 
 43             Type objType = Type.GetType("System.Object");
 44             ConstructorInfo objCtor = objType.GetConstructor(new Type[0]);
 45 
 46             ConstructorBuilder pointCtor = pointTypeBld.DefineConstructor(
 47                                         MethodAttributes.Public,
 48                                         CallingConventions.Standard,
 49                                         ctorParams);
 50             ILGenerator ctorIL = pointCtor.GetILGenerator();
 51 
 52 
 53             // First, you build the constructor. 首先,你建立的构造
 54             ctorIL.Emit(OpCodes.Ldarg_0);
 55             ctorIL.Emit(OpCodes.Call, objCtor);
 56             ctorIL.Emit(OpCodes.Ldarg_0);
 57             ctorIL.Emit(OpCodes.Ldarg_1);
 58             ctorIL.Emit(OpCodes.Stfld, xField);
 59             ctorIL.Emit(OpCodes.Ldarg_0);
 60             ctorIL.Emit(OpCodes.Ldarg_2);
 61             ctorIL.Emit(OpCodes.Stfld, yField);
 62             ctorIL.Emit(OpCodes.Ret);
 63 
 64             //  Now, you'll build a method to output some information on the
 65             // inside your dynamic class. This method will have the following
 66             // definition in C#:
 67             //  public void WritePoint()
 68             //现在,你将建立一个方法来输出一些信息
 69             //内部动态类。这种方法将有以下
 70             //在C#中定义:
 71             //公共的无效WritePoint ( )
 72 
 73             MethodBuilder writeStrMthd = pointTypeBld.DefineMethod(
 74                                           "WritePoint",
 75                                   MethodAttributes.Public,
 76                                                   typeof(void),
 77                                                   null);
 78 
 79 
 80             ILGenerator writeStrIL = writeStrMthd.GetILGenerator();
 81 
 82             // The below ILGenerator created demonstrates a few ways to create
 83             // string output through STDIN. 
 84             // ILGenerator.EmitWriteLine(string) will generate a ldstr and a 
 85             // call to WriteLine for you.
 86             //创建下面的ILGenerator演示了几种方法来创建
 87             //字符串通过标准输入输出。
 88             // ILGenerator.EmitWriteLine的(字符串)将生成一个ldstr与一个
 89             //调用你的WriteLine 。
 90 
 91             writeStrIL.EmitWriteLine("这个当前实例的值是:");
 92 
 93             // Here, you will do the hard work yourself. First, you need to create
 94             // the string we will be passing and obtain the correct WriteLine overload
 95             // for said string. In the below case, you are substituting in two values,
 96             // so the chosen overload is Console.WriteLine(string, object, object).
 97             //这里,你会做自己的辛勤工作。首先,你需要创建
 98             //字符串,我们将通过并获得正确的WriteLine超载
 99             //表示字符串。在下面的情况下,你是在两个值代
100 
101             String inStr = "({0}, {1})";
102             Type[] wlParams = new Type[] {typeof(string),
103                      typeof(object),
104                      typeof(object)};
105 
106             // We need the MethodInfo to pass into EmitCall later.
107             //我们的MethodInfo ,到EmitCall通过后的。
108 
109             MethodInfo writeLineMI = typeof(Console).GetMethod(
110                                  "WriteLine",
111                              wlParams);
112 
113             // Push the string with the substitutions onto the stack.
114             // This is the first argument for WriteLine - the string one. 
115             //推到堆栈上替换的字符串。
116             //这是第一个参数的WriteLine - 一个字符串。
117 
118             writeStrIL.Emit(OpCodes.Ldstr, inStr);
119 
120             // Since the second argument is an object, and it corresponds to
121             // to the substitution for the value of our integer field, you 
122             // need to box that field to an object. First, push a reference
123             // to the current instance, and then push the value stored in
124             // field 'x'. We need the reference to the current instance (stored
125             // in local argument index 0) so Ldfld can load from the correct
126             // instance (this one).
127             //由于第二个参数是一个对象,它对应于
128             //我们的整数字段的值替代,你
129             //需要框字段对象。首先,推动一个参考
130             //当前实例,然后推值存储在
131             //字段'X' 。我们需要对当前实例的引用(存储
132             //本地参数索引0 ),因此Ldfld可以从正确的加载
133             //实例(一) 。
134 
135             writeStrIL.Emit(OpCodes.Ldarg_0);
136             writeStrIL.Emit(OpCodes.Ldfld, xField);
137 
138             // Now, we execute the box opcode, which pops the value of field 'x',
139             // returning a reference to the integer value boxed as an object.
140             //现在,我们执行操作码框,弹出领域的'X'的价值,
141             //返回一个整型值作为一个对象盒装的参考。
142 
143             writeStrIL.Emit(OpCodes.Box, typeof(int));
144 
145             // Atop the stack, you'll find our string inStr, followed by a reference
146             // to the boxed value of 'x'. Now, you need to likewise box field 'y'.
147             //堆栈上面,你会发现我们的字符串INSTR ,其次是参考
148             // 'x'的装箱值。现在,你需要同样框场'Y' 。
149 
150             writeStrIL.Emit(OpCodes.Ldarg_0);
151             writeStrIL.Emit(OpCodes.Ldfld, yField);
152             writeStrIL.Emit(OpCodes.Box, typeof(int));
153 
154             // Now, you have all of the arguments for your call to
155             // Console.WriteLine(string, object, object) atop the stack:
156             // the string InStr, a reference to the boxed value of 'x', and
157             // a reference to the boxed value of 'y'.
158 
159             // Call Console.WriteLine(string, object, object) with EmitCall.
160             //现在,你有你的电话所有的参数
161             // Console.WriteLine (字符串,对象,对象)之上的堆栈:
162             //字符串INSTR , 'x'的装箱值的引用,
163             //装箱的值'Y'的参考。
164 
165             //调用Console.WriteLine与EmitCall (字符串,对象,对象) 。
166 
167             writeStrIL.EmitCall(OpCodes.Call, writeLineMI, null);
168 
169             // Lastly, EmitWriteLine can also output the value of a field
170             // using the overload EmitWriteLine(FieldInfo).
171             //最后, EmitWriteLine也可以输出字段值
172             //使用的超载EmitWriteLine (的FieldInfo ) 。
173 
174             writeStrIL.EmitWriteLine("The value of 'x' is:");
175             writeStrIL.EmitWriteLine(xField);
176             writeStrIL.EmitWriteLine("The value of 'y' is:");
177             writeStrIL.EmitWriteLine(yField);
178 
179             // Since we return no value (void), the the ret opcode will not
180             // return the top stack value.
181             //由于我们没有返回值(无效) , ret操作码不会
182             //返回栈顶值。
183 
184             writeStrIL.Emit(OpCodes.Ret);
185  
186 
187             Type type1 = pointTypeBld.CreateType();
188             object[] ctorParams1 = new object[2];
189 
190             Console.Write("Enter a integer value for X: ");
191             string myX = Console.ReadLine();
192             Console.Write("Enter a integer value for Y: ");
193             string myY = Console.ReadLine();
194 
195             Console.WriteLine("---");
196 
197             ctorParams1[0] = Convert.ToInt32(myX);
198             ctorParams1[1] = Convert.ToInt32(myY);
199 
200             Type ptType = type1;
201 
202             object ptInstance = Activator.CreateInstance(ptType, ctorParams1);
203             ptType.InvokeMember("WritePoint",
204                     BindingFlags.InvokeMethod,
205                     null,
206                     ptInstance,
207                     new object[0]);
208 
209             myAsmBuilder.Save("Point.dll");
210             //return type1;
211 
212         }
213     }
214 }
调用View Code
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Reflection;
 6 using System.Reflection.Emit;
 7 
 8 namespace Reflx_Method
 9 {
10    
11     class Program
12     {
13        
14         static void Main(string[] args)
15         {
16             new Class1().CreateDynamicType();
17         }
18          
19     } 
20 
21 }
22  
等价于View Code
 1 public class Point1
 2 {
 3     // Fields
 4     public int x;
 5     public int y;
 6 
 7     // Methods
 8     public Point1(int num1, int num2)
 9     {
10         this.x = num1;
11         this.y = num2;
12     }  
13     public void WritePoint()
14     {
15         Console.WriteLine("这个当前实例的值是:");
16         Console.WriteLine("({0}, {1})", this.x, this.y);
17         Console.WriteLine("The value of 'x' is:");
18         Console.Out.WriteLine(this.x);
19         Console.WriteLine("The value of 'y' is:");
20         Console.Out.WriteLine(this.y);
21     }
22 }
23 
24  


Demo

原文地址:https://www.cnblogs.com/kubimiantiao/p/2456805.html