主要代码 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