zoukankan      html  css  js  c++  java
  • 高性能反射初体验2

    主要代码 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       
     16         
     17 
     18       
     19         /// <summary>
     20         /// BeginCatchBlock()用法
     21         /// </summary>
     22         public void ILGenerator_BeginCatchBlock()
     23         {
     24             AppDomain current = AppDomain.CurrentDomain;
     25             AssemblyName myAsmName = new AssemblyName();
     26             myAsmName.Name = "AdderExceptionAsm";
     27             AssemblyBuilder myAsmBldr = current.DefineDynamicAssembly(myAsmName,
     28                                      AssemblyBuilderAccess.RunAndSave);
     29 
     30             ModuleBuilder myModBldr = myAsmBldr.DefineDynamicModule(myAsmName.Name,
     31                                myAsmName.Name + ".dll");
     32             //internal class Adder{
     33 
     34             TypeBuilder myTypeBldr = myModBldr.DefineType("Adder");
     35 
     36             
     37 
     38             // This method will add two numbers which are 100 or less. If either of the 此方法将添加两个数字是100或更少。如果任
     39             // passed integer vales are greater than 100, it will throw an exception. 通过整数山谷大于100 ,它会抛出一个异常
     40         
     41             //  public static int DoAdd(int num1, int num2){
     42             //参数
     43 
     44             Type[] adderParams = new Type[] { typeof(int), typeof(int) };
     45             ///DoAdd方法
     46             MethodBuilder adderBldr = myTypeBldr.DefineMethod("DoAdd",
     47                                MethodAttributes.Public |
     48                                MethodAttributes.Static,
     49                                typeof(int),
     50                                adderParams);
     51 
     52             ILGenerator adderIL = adderBldr.GetILGenerator();
     53 
     54             // Types and methods used in the code to throw, catch, and 抛出,捕捉,在代码中使用的类型和方法
     55             // display OverflowException. Note that if the catch block were 显示引发OverflowException 。请注意,如果catch块
     56             // for a more general type, such as Exception, we would need  更普遍的类型,如异常,我们需要
     57             // a MethodInfo for that type's ToString method.  该类型的ToString方法的MethodInfo 。
     58 
     59             //    OverflowException exception = new OverflowException("Cannot accept values over 100 for add."); throw new OverflowException();
     60             ///
     61             /// <summary>
     62             /// OverflowException异常Type
     63             /// </summary>
     64             Type overflow = typeof(OverflowException);
     65             ConstructorInfo exCtorInfo = overflow.GetConstructor(
     66                               new Type[] { typeof(string) });
     67             //  Console.WriteLine("Caught {0}", exception1.ToString());
     68 
     69             ///OverflowException异常Type的ToString方法
     70             MethodInfo exToStrMI = overflow.GetMethod("ToString");
     71             ///Console对象Type的WriteLine方法
     72             MethodInfo writeLineMI = typeof(Console).GetMethod("WriteLine",
     73                               new Type[] 
     74                         {typeof(string),
     75                          typeof(object)});
     76            // int num;
     77             ///局部变量 int num
     78             LocalBuilder tmp1 = adderIL.DeclareLocal(typeof(int));
     79 
     80             ///OverflowException exception1 异常变量 
     81             LocalBuilder tmp2 = adderIL.DeclareLocal(overflow);
     82 
     83             // In order to successfully branch, we need to create labels  为了成功的分支,我们需要创建标签
     84             // representing the offset IL instruction block to branch to. 代表跳转到偏移的IL指令块。
     85             // These labels, when the MarkLabel(Label) method is invoked, 这些标签的MarkLabel (标签)方法被调用时,
     86             // will specify the IL instruction to branch to.   将跳转到指定的IL指令
     87             // 
     88             ///标签1
     89             Label failed = adderIL.DefineLabel();
     90             ///标签2
     91             Label endOfMthd = adderIL.DefineLabel();
     92 
     93             /// Begin the try block. 开始的try块。  try{ 
     94             Label exBlock = adderIL.BeginExceptionBlock();
     95 
     96           
     97           
     98            
     99             // First, load argument 0 and the integer value of "100" onto the  首先,加载参数0和整数值到“100"
    100             adderIL.Emit(OpCodes.Ldarg_0);
    101             // stack. If arg0 > 100, branch to the label "failed", which is marked  叠加。如果arg0的> 100,分支标签“失败” ,这标志着
    102             adderIL.Emit(OpCodes.Ldc_I4_S, 100);
    103             // as the address of the block that throws an exception.  块抛出一个异常的地址
    104             adderIL.Emit(OpCodes.Bgt_S, failed);
    105 
    106 
    107 
    108             // branching unconditionally to the instruction at the label "endOfMthd". 无条件分支的指令在标签“ endOfMthd ” 。
    109            
    110             adderIL.Emit(OpCodes.Ldarg_1);
    111             // Now, check to see if argument 1 was greater than 100. If it was,  现在,请检查,如果参数1大于100 。如果是,
    112             adderIL.Emit(OpCodes.Ldc_I4_S, 100);
    113             // branch to "failed." Otherwise, fall through and perform the addition, 分支“失败。 ”否则,属于通过并执行另外,
    114             adderIL.Emit(OpCodes.Bgt_S, failed);
    115 
    116             //参数0
    117             adderIL.Emit(OpCodes.Ldarg_0);
    118             //参数1
    119             adderIL.Emit(OpCodes.Ldarg_1);
    120             //无符号相加
    121             adderIL.Emit(OpCodes.Add_Ovf_Un);
    122             // Store the result of the addition. 存储在另外的结果。
    123             adderIL.Emit(OpCodes.Stloc_S, tmp1); 
    124 
    125             adderIL.Emit(OpCodes.Br_S, endOfMthd);
    126 
    127             // If one of the arguments was greater than 100, we need to throw an  如果一个参数是大于100 ,我们需要抛出
    128             // exception. We'll use "OverflowException" with a customized message. 例外。我们将使用一个定制的消息“引发OverflowException ” 。
    129             // First, we load our message onto the stack, and then create a new   首先,我们加载到堆栈上我们的信息,然后创建一个新的
    130             // exception object using the constructor overload that accepts a 使用构造函数重载,它接受一个异常对象
    131             // string message.  字符串消息
    132             // OverflowException exception = new OverflowException("不能接受的增加值超过100 。.");
    133 
    134             adderIL.MarkLabel(failed);
    135             adderIL.Emit(OpCodes.Ldstr, "不能接受的增加值超过100 。");
    136             adderIL.Emit(OpCodes.Newobj, exCtorInfo);
    137 
    138             // We're going to need to refer to that exception object later, so let's 我们要需要参考该异常对象后,让我们
    139             // store it in a temporary variable. Since the store function pops the 存储在一个临时变量。由于存储功能弹出
    140             // the value/reference off the stack, and we'll need it to throw the 堆栈的值/参考,我们需要它扔
    141             // exception, we will subsequently load it back onto the stack as well.例外,我们将随后加载它放回堆栈以及。
    142              
    143             adderIL.Emit(OpCodes.Stloc_S, tmp2);
    144             adderIL.Emit(OpCodes.Ldloc_S, tmp2);
    145 
    146             // Throw the exception now on the stack. 现在抛出异常堆栈  throw new OverflowException();
    147 
    148             adderIL.ThrowException(overflow);
    149 
    150             // Start the catch block for OverflowException.
    151             /// 开始为引发OverflowException catch块。 
    152             adderIL.BeginCatchBlock(overflow);
    153 
    154             // When we enter the catch block, the thrown exception    当我们进入catch块,抛出异常
    155             // is on the stack. Store it, then load the format string  是在堆栈上。储存,然后加载格式字符串
    156             // for WriteLine. 的WriteLine 。
    157 
    158             //
    159             adderIL.Emit(OpCodes.Stloc_S, tmp2);
    160             adderIL.Emit(OpCodes.Ldstr, "Caught {0}");
    161 
    162             // Push the thrown exception back on the stack, then   推抛出的异常堆栈上的背部,然后
    163             // call its ToString() method. Note that if this catch block 调用其ToString ()方法。请注意,如果该catch块
    164             // were for a more general exception type, like Exception,  为更一般的异常类型,如异常
    165             // it would be necessary to use the ToString for that type. 就必须使用这种类型的ToString 。
    166             // Console.WriteLine("Caught {0}", exception1.ToString());
    167 
    168             adderIL.Emit(OpCodes.Ldloc_S, tmp2);
    169             adderIL.EmitCall(OpCodes.Callvirt, exToStrMI, null);
    170 
    171             // The format string and the return value from ToString() are 格式字符串的ToString()的返回值
    172             // now on the stack. Call WriteLine(string, object). 现在堆栈。调用的WriteLine (字符串,对象) 。
    173             //
    174             adderIL.EmitCall(OpCodes.Call, writeLineMI, null);
    175 
    176             // Since our function has to return an integer value, we'll load -1 onto 因为我们的函数返回一个整型值,我们将载入-1到
    177             // the stack to indicate an error, and store it in local variable tmp1. 堆栈显示一个错误,它存储在局部变量TMP1 。
    178             // num = -1;
    179 
    180             adderIL.Emit(OpCodes.Ldc_I4_M1);
    181             adderIL.Emit(OpCodes.Stloc_S, tmp1);
    182 
    183             // End the exception handling block.  num = -1;
    184 
    185 
    186             adderIL.EndExceptionBlock();
    187 
    188             // The end of the method. If no exception was thrown, the correct value  该方法的结束。如果没有异常被抛出,正确的值
    189             // will be saved in tmp1. If an exception was thrown, tmp1 will be equal  将被保存在TMP1 。如果一个异常被抛出, TMP1将等于
    190             // to -1. Either way, we'll load the value of tmp1 onto the stack and return. -1。无论哪种方式,我们将加载到堆栈,并返回TMP1价值。
    191             // return num;
    192 
    193             adderIL.MarkLabel(endOfMthd);
    194             adderIL.Emit(OpCodes.Ldloc_S, tmp1);
    195             adderIL.Emit(OpCodes.Ret);
    196 
    197            
    198 
    199             Type adderType = myTypeBldr.CreateType();
    200 
    201             object addIns = Activator.CreateInstance(adderType);
    202 
    203             object[] addParams = new object[2];
    204 
    205             Console.Write("Enter an integer value: ");
    206             addParams[0] = (object)Convert.ToInt32(Console.ReadLine());
    207 
    208             Console.Write("Enter another integer value: ");
    209             addParams[1] = (object)Convert.ToInt32(Console.ReadLine());
    210 
    211             Console.WriteLine("If either integer was > 100, an exception will be thrown.");
    212             Console.WriteLine("---");
    213 
    214             Console.WriteLine("{0} + {1} = {2}",
    215                   addParams[0], addParams[1],
    216                   adderType.InvokeMember("DoAdd",
    217                      BindingFlags.InvokeMethod,
    218                      null,
    219                      addIns,
    220                      addParams));
    221             myAsmBldr.Save("AdderExceptionAsm.dll");
    222           
    223         }
    224         
    225         /// <summary>
    226         /// BeginScope()与EndScope()用法
    227         /// </summary>
    228         public void ILGenerator_Begin_End_Scope()
    229         {
    230             // 获取当前AppDomain 。
    231 
    232             AppDomain myAppDomain = AppDomain.CurrentDomain;
    233             AssemblyName myAssemblyName = new AssemblyName();
    234             myAssemblyName.Name = "SampleAssembly";
    235 
    236             // Create a dynamic assembly 'myAssembly' with access mode 'Run'.创建一个动态的组装与访问模式“运行” “ myAssembly的” 。
    237 
    238             AssemblyBuilder myAssembly = myAppDomain.DefineDynamicAssembly(
    239                                     myAssemblyName, AssemblyBuilderAccess.RunAndSave);
    240             // Create a dynamic module 'myModule' in 'myAssembly'. 创建一个动态模块myAssembly的“ MyModule的” 。
    241 
    242             ModuleBuilder myModule = myAssembly.DefineDynamicModule("MyDynamicModule", "MyDynamicModule.dll", true);
    243             // Define a public class 'MyDynamicClass'.  定义一个公共类的“ MyDynamicClass ' 。
    244 
    245             TypeBuilder myTypeBuilder = myModule.DefineType("MyDynamicClass",
    246                                              TypeAttributes.Public);
    247             // Define a public string field.  定义一个公共的字符串字段。
    248 
    249             FieldBuilder myField = myTypeBuilder.DefineField("MyDynamicField1",
    250                                      typeof(String), FieldAttributes.Public);
    251             // Create the constructor.  创建构造。
    252 
    253             Type[] myConstructorArgs = { typeof(String) };
    254             ConstructorBuilder myConstructor = myTypeBuilder.DefineConstructor(
    255                MethodAttributes.Public, CallingConventions.Standard, myConstructorArgs);
    256             ConstructorInfo mySuperConstructor = typeof(Object).GetConstructor(new Type[0]);
    257             // Generate IL for 'myConstructor'.  生成IL ' myConstructor “ ”
    258 
    259             ILGenerator myConstructorIL = myConstructor.GetILGenerator();
    260             // Emit the necessary opcodes. 发出了必要的操作码
    261 
    262             myConstructorIL.Emit(OpCodes.Ldarg_0); 
    263             myConstructorIL.Emit(OpCodes.Call, mySuperConstructor);
    264             myConstructorIL.Emit(OpCodes.Ldarg_0);
    265             myConstructorIL.Emit(OpCodes.Ldarg_1);
    266             myConstructorIL.Emit(OpCodes.Stfld, myField);
    267             myConstructorIL.Emit(OpCodes.Ret);
    268 
    269             // Define a dynamic method named 'MyDynamicMethod'.  定义和动态的方法,名为“ MyDynamicMethod
    270 
    271         
    272 
    273             
    274             MethodBuilder myMethod = myTypeBuilder.DefineMethod("MyDynamicMethod",
    275                MethodAttributes.Public | MethodAttributes.SpecialName, typeof(string), Type.EmptyTypes);
    276             // Generate IL for 'myMethod'.
    277             ILGenerator myMethodIL = myMethod.GetILGenerator();
    278 
    279             // Begin the scope for a local variable.开始的一个局部变量的范围。
    280 
    281             myMethodIL.BeginScope();
    282 
    283             LocalBuilder myLocalBuilder = myMethodIL.DeclareLocal(typeof(int));
    284 
    285             LocalBuilder shili = myMethodIL.DeclareLocal(typeof(int));
    286             Console.WriteLine("\n试图访问的范围内,局部变量.");
    287             Console.WriteLine("'myLocalBuilder' type is: {0}", myLocalBuilder.LocalType);
    288             myMethodIL.Emit(OpCodes.Ldstr, "Local value");
    289             myMethodIL.Emit(OpCodes.Stloc_0, myLocalBuilder);
    290 
    291             
    292              myMethodIL.Emit(OpCodes.Ldstr, "Local value111");
    293              myMethodIL.Emit(OpCodes.Stloc_S, shili);
    294 
    295 
    296 
    297 
    298              Console.WriteLine("\n试图访问的范围内,局部变量.");
    299              Console.WriteLine("'myLocalBuilder' type is: {0}", shili.LocalType);
    300 
    301            
    302             // End the scope of 'myLocalBuilder'.
    303             myMethodIL.EndScope();
    304 
    305             // Access the local variable outside the scope.
    306             Console.WriteLine("\nTrying to access the local variable outside the scope:");
    307             myMethodIL.Emit(OpCodes.Stloc_0, myLocalBuilder);
    308             myMethodIL.Emit(OpCodes.Ldloc_S, shili);
    309             myMethodIL.Emit(OpCodes.Ret);
    310 
    311             // Create 'MyDynamicClass' class.
    312             Type myType1 = myTypeBuilder.CreateType();
    313 
    314 
    315             myAssembly.Save("MyDynamicModule.dll");
    316         }
    317 
    318 
    319        
    320 
    321         
    322 
    323 
    324     }
    325 }
    调用代码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().ILGenerator_Begin_End_Scope();
    17 
    18             new Class1().ILGenerator_BeginCatchBlock();
    19 
    20         }
    21          
    22     } 
    23 
    24 }
    25  
    方法ILGenerator_BeginCatchBlock()等效View Code
     1 public class Adder
     2 {
     3     // Methods
     4     public static int DoAdd(int num1, int num2)
     5     {
     6         int num;
     7         OverflowException exception;
     8         try
     9         {
    10             if ((num1 <= 100) && (num2 <= 100))
    11             {
    12                 return (num1 + num2);
    13             }
    14             exception = new OverflowException("不能接受超过100的参数");
    15             throw new OverflowException();
    16         }
    17         catch (OverflowException exception2)
    18         {
    19             Console.WriteLine("捕捉 {0}{1}", exception.ToString(), exception2.ToString());
    20             num = -1;
    21         }
    22         return num;
    23     }
    24 }
    25 
    26  
    方法ILGenerator_Begin_End_Scope()等效View Code1
     1 public class MyDynamicClass
     2 {
     3     // Fields
     4     public string MyDynamicField1;
     5 
     6     // Methods
     7     public MyDynamicClass(string text1)
     8     {
     9         this.MyDynamicField1 = text1;
    10     }
    11 
    12     public string MyDynamicMethod()
    13     {
    14         int num2 = "Local value111";
    15         return (string) num2;
    16     }
    17 }
    18 
    19  

     

    DEMO

  • 相关阅读:
    Python编程题24--回文数
    Python编程题23--移动零
    Python编程题22--只出现一次的数字
    Python编程题21--每日温度
    Python编程题20--最大子序和
    Python编程题19--比特位计数
    推荐系统中对比实验工具--伯乐bole
    pytorch中反向传播的loss.backward(retain_graph=True)报错
    win10彻底禁止自动更新(家庭版操作)
    linux使用清华源安装工具,切换清华源
  • 原文地址:https://www.cnblogs.com/kubimiantiao/p/2455677.html
Copyright © 2011-2022 走看看