zoukankan      html  css  js  c++  java
  • 高性能反射初体验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

  • 相关阅读:
    MarkDownPad2 注册码
    如何让你的.vue在sublime text 3 中变成彩色?
    字典树入门
    博弈论
    复杂度问题
    gets scanf以及缓冲区域的问题
    对象
    矩阵转置的一般算法
    二叉树的建立、遍历、叶子节点计数、深度计算
    D
  • 原文地址:https://www.cnblogs.com/kubimiantiao/p/2456805.html
Copyright © 2011-2022 走看看