Lambda Master's Road Part III

Source: Internet
Author: User

Turn http://www.cnblogs.com/lazycoding/archive/2013/01/06/2847587.html

Behind the secret-msil

With the famous LINQPad, we can look at the MSIL code in more depth without any secrets. is a linqpad to use

We will look at three examples, the first lambda expression is as follows:

action<string> Dosomethinglambda = (s) + ={    Console.WriteLine (s);  + local};   

The corresponding normal function is this

action<string> Dosomethinglambda = (s) + ={    Console.WriteLine (s);  + local};   

The resulting MSIL code snippet is as follows:

dosomethingnormal:il_0000:  nop         il_0001:  ldarg.  1     il_0002:  call        System.Console.WriteLineIL_0007:  nop         il_0008:  ret         <main >b__0:il_0000:  nop         il_0001:  ldarg.  0     

The biggest difference is that the method has a different name usage. Rather than declarations. In fact. The declaration is exactly the same. The compiler creates a new method within the class to implement this method. It's nothing new, just for us to use lambda expressions to make it easy to write code. From the MSIL code, we did the same thing. A method is called in the current object.

We'll show you the changes made by the compiler. In this legend. We can see that the compiler moved the lambda expression into a fixed method.


The second example shows the real magic of lambda expressions, in this case. We used both a normal method with global variables and a lambda expression with a captured variable. The code is as follows

voidMain () {int local =5; action<String> Dosomethinglambda = (s) = ={Console.WriteLine (s + local);}; global = local; Dosomethinglambda ("Test 1"); Dosomethingnormal ("Test 2"); int global;  void Dosomethingnormal (string s) {Console.WriteLine (s + global);}      

There's nothing different about it. The key is: How lambda expressions are handled by the compiler

Il_0000:newobj userquery+<>C__displayclass1. Ctoril_0005:stloc.1Il_0006:nop Il_0007:ldloc.1IL_0008:ldc.i4.5IL_0009:STFLD userquery+<>C__DisplayClass1.localIL_000E:ldloc.1IL_000F:LDFTN userquery+<>c__displayclass1.<main>B__0il_0015:newobj system.action<system.string>.. Ctoril_001a:stloc.0Il_001b:ldarg.0Il_001c:ldloc.1IL_001D:LDFLD userquery+<>C__DISPLAYCLASS1.LOCALIL_0022:STFLD UserQuery.GlobalIl_0027:ldloc.0Il_0028:ldstr"Test 1"Il_002d:callvirt system.action<system.string>. Invokeil_0032:nop Il_0033:ldarg.0Il_0034:ldstr"Test 2"Il_0039:call UserQuery.DoSomethingNormalIL_003E:nop DoSomethingNormal:IL_0000:nop Il_0001:ldarg.1Il_0002:ldarg.0 il_0003:ldfld userquery. Globalil_0008:box System.Int32IL_000D:call System.String.ConcatIL_0012:call System.Console.WriteLineIL_0017:nop Il_0018:ret <>c__DisplayClass1.<Main> b__0:il_0000:nop Il_0001:ldarg. 1 Il_0002:ldarg. 0 il_0003:ldfld userquery+<>c__ DisplayClass1.localIL_0008:box System.Int32IL_000D:call System.String.ConcatIL_0012:call System.Console.WriteLineIL_0017:nop il_0018:ret <>c__displayclass1. Ctor:IL_0000:ldarg. 0 Il_0001:call System.Object. Ctoril_0006:ret             

As in the first example. The same mechanism. The compiler moves the lambda expression into a method. But the difference is that the compiler also generated a class this time. The method that the compiler generates for our lambda expression is placed in the class, which gives the captured variable a global scope, by doing so. A lambda expression can access a local variable. Because in MSIL. It is a global variable inside a class instance.

All variables can therefore be assigned/read in the object of the newly generated class. This resolves the reference problem between the variables. (In fact, only references to that class instance are preserved.) The compiler is also smart enough to put the captured variables inside the class. Therefore, there is not much performance problem when we use lambda. Anyway. Attention. A memory leak can be caused by maintaining a reference to the lambda expression. As long as the method is still there. The variable is still alive. Obvious. And now we know the reason.

Once again, we use illustrations to illustrate. In the case of this kind of closure. Not only will the method be moved. The captured variables will also be moved. All objects that have been moved are placed in a newly generated class. Therefore, a class without a name appears implicitly.

Lambda Master's Road Part III

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.