Emit Learning (3), emit Learning

Source: Internet
Author: User
Tags mscorlib

Emit Learning (3), emit Learning

I was going to directly access Dapper, but I checked a lot of content yesterday. Dapper is a mature framework. It is very practical to consider various situations, however, this makes it impossible for me to finish reading it in a short time, so I have to wait for a few days.

Let's take a look at the loop and exceptions. When we look at the IL jump, there is a tag that jumps and jumps. In OpCodes, there is a corresponding implementation.

I. Example

public static void Xunhuan(int num)        {            try            {                int sum = 0;                if (num < 1)                {                    throw new Exception("num is less than 1");                }                for (int i = 1; i <= num; i++)                {                    sum += i;                }                Console.WriteLine("executed successfully : Sum = " + sum);            }            catch (Exception e)            {                Console.WriteLine("error happened : " + e.Message);            }        }

When calling Xunhuan (), when a value smaller than 1 is passed in, an exception is thrown to go to The Exception Handling Section. Otherwise, the exception enters the loop (here for demonstration, a loop is used, otherwise, use the algorithm to calculate the result), Sum. as a result, I will not post it.

 

Ii. OpCodes implementation

Static Action <int> action; static void Main (string [] args) {// defines a dynamic method var method = new DynamicMethod ("Xunhuan", null, new Type [] {typeof (int)}); ILGenerator IL = method. getILGenerator (); // defines the label var label1 = IL. defineLabel (); var xunLabel = IL. defineLabel (); var endLabel = IL. defineLabel (); // defines the local variable var sum = IL. declareLocal (typeof (int); var I = IL. declareLocal (typeof (int); IL. emit (OpCodes. ldc_I4_0); IL. emit (OpCodes. stloc_0); // sum = 0 IL. emit (OpCodes. ldc_I4_1); IL. emit (OpCodes. stloc_1); // I = 1 IL. emit (OpCodes. ldstr, "enter number: num ="); IL. emit (OpCodes. ldarg_0); // the implementation method is to pack IL. emit (OpCodes. box, typeof (int); // boxed IL. emit (OpCodes. call, typeof (string ). getMethod ("Concat", new Type [] {typeof (string), typeof (object)}); IL. emit (OpCodes. call, typeof (Console ). getMethod ("WriteLine", new Type [] {typeof (string)}); Label tryLabel = IL. beginExceptionBlock (); // try IL. emit (OpCodes. ldarg_0); // num IL. emit (OpCodes. ldc_I4_1); // 1 IL. emit (OpCodes. bge, label1); // num> = 1-> label1, note: the jump in the try cannot jump out of the try statement, but can only be in the internal IL. emit (OpCodes. ldstr, "num is less than 1"); IL. emit (OpCodes. newobj, typeof (Exception ). getConstructor (new Type [] {typeof (string)}); // new Exception (); IL. emit (OpCodes. throw); // throw IL. markLabel (label1); IL. emit (OpCodes. ldloc_1); // I IL. emit (OpCodes. ldarg_0); // num IL. emit (OpCodes. bgt, xunLabel); // I> num-> endLabel IL. emit (OpCodes. ldloc_0); IL. emit (OpCodes. ldloc_1); IL. emit (OpCodes. add); IL. emit (OpCodes. stloc_0); // sum + = I; IL. emit (OpCodes. ldloc_1); IL. emit (OpCodes. ldc_I4_1); IL. emit (OpCodes. add); IL. emit (OpCodes. stloc_1); // I + = 1; IL. emit (OpCodes. br_S, label1); IL. markLabel (xunLabel); IL. emit (OpCodes. ldstr, "executed successfully: Sum ="); IL. emit (OpCodes. ldloc_0); // method 2 call Convert. toString (int num) method IL. emit (OpCodes. call, typeof (Convert ). getMethod ("ToString", new Type [] {typeof (int)}); IL. emit (OpCodes. call, typeof (string ). getMethod ("Concat", new Type [] {typeof (string), typeof (string)}); IL. emit (OpCodes. call, typeof (Console ). getMethod ("WriteLine", new Type [] {typeof (object)}); IL. markLabel (endLabel); IL. emit (OpCodes. nop); IL. beginCatchBlock (typeof (Exception); // catch IL. emit (OpCodes. callvirt, typeof (Exception ). getMethod ("get_Message"); IL. emit (OpCodes. call, typeof (Console ). getMethod ("WriteLine", new Type [] {typeof (string)}); IL. endExceptionBlock (); // end IL. emit (OpCodes. ret); action = (Action <int>) method. createDelegate (typeof (Action <int>); // call the method by Delegate, instead of saving it as a dll file on the Console. writeLine ("------------- normal execution ---------------"); action. invoke (10); Console. writeLine ("------------- abnormal execution -------------"); action. invoke (-10); Console. readKey ();}

The implementation method is not the only one. The method I wrote is not the simplest. Below I will post the reflector decompiled IL code, which is quite different from what I wrote.

   .method public hidebysig static void Xunhuan(int32 num) cil managed    {        .maxstack 2        .locals init (            [0] int32 num2,            [1] int32 num3,            [2] class [mscorlib]System.Exception exception,            [3] bool flag)        L_0000: nop         L_0001: nop         L_0002: ldc.i4.0         L_0003: stloc.0         L_0004: ldarg.0         L_0005: ldc.i4.1         L_0006: clt         L_0008: ldc.i4.0         L_0009: ceq         L_000b: stloc.3         L_000c: ldloc.3         L_000d: brtrue.s L_001b        L_000f: nop         L_0010: ldstr "num is less than 1"        L_0015: newobj instance void [mscorlib]System.Exception::.ctor(string)        L_001a: throw         L_001b: ldc.i4.1         L_001c: stloc.1         L_001d: br.s L_0029        L_001f: nop         L_0020: ldloc.0         L_0021: ldloc.1         L_0022: add         L_0023: stloc.0         L_0024: nop         L_0025: ldloc.1         L_0026: ldc.i4.1         L_0027: add         L_0028: stloc.1         L_0029: ldloc.1         L_002a: ldarg.0         L_002b: cgt         L_002d: ldc.i4.0         L_002e: ceq         L_0030: stloc.3         L_0031: ldloc.3         L_0032: brtrue.s L_001f        L_0034: ldstr "executed successfully : Sum = "        L_0039: ldloc.0         L_003a: box int32        L_003f: call string [mscorlib]System.String::Concat(object, object)        L_0044: call void [mscorlib]System.Console::WriteLine(string)        L_0049: nop         L_004a: nop         L_004b: leave.s L_0068        L_004d: stloc.2         L_004e: nop         L_004f: ldstr "error happened : "        L_0054: ldloc.2         L_0055: callvirt instance string [mscorlib]System.Exception::get_Message()        L_005a: call string [mscorlib]System.String::Concat(string, string)        L_005f: call void [mscorlib]System.Console::WriteLine(string)        L_0064: nop         L_0065: nop         L_0066: leave.s L_0068        L_0068: nop         L_0069: ret         .try L_0001 to L_004d catch [mscorlib]System.Exception handler L_004d to L_0068    }

In the past, I was always lazy. I had to look at and understand new knowledge. But in the actual writing process, I encountered a lot of problems that I would not encounter, the code can be written without looking at it. It is better to have a good memory than a bad pen. You have to repeat the code row by row to find the problem.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.