C # closure problem-have you ever been passed by & rdquo; pitfall & ldquo ?,

Source: Internet
Author: User

C # closure problem-have you ever been "pitted ?,
Introduction

What is a closure? This term was found only when I read the interview questions.

What problems does closures have in actual projects? Now let's take a look at this unfamiliar term.

If anonymous functions and lamada expressions are used in actual work, you should pay close attention to them.

 

Problem

What are the output results of this code?

public static void Main(){    Console.WriteLine("Starting.");    for (int i = 0; i < 4; ++i)        Task.Run(() => Console.WriteLine(i));    Console.WriteLine("Finished. Press <ENTER> to exit.");    Console.ReadLine();}

Output result:

Starting.Finished. Press <ENTER> to exit.4444

Are you correct? If not, follow me to find out the underlying reasons.

 

Problem Solving
public static void Main(){    Console.WriteLine("Starting.");    for (int i = 0; i < 4; ++i)    {        int j = i;        Task.Run(() => Console.WriteLine(j));    }    Console.WriteLine("Finished. Press <ENTER> to exit.");    Console.ReadLine();}

Output result

Starting.Finished. Press <ENTER> to exit.0132

 

What is the cause analysis closure?
using System;class Test{    static void Main()    {        Action action = CreateAction();        action();        action();    }    static Action CreateAction()    {        int counter = 0;        return delegate        {            // Yes, it could be done in one statement;             // but it is clearer like this.            counter++;            Console.WriteLine("counter={0}", counter);        };    }}

Output

counter=1counter=2
  

In essence, a closure is a block of code which can be executed at a later time, but which maintains the environment in which it was first created - i.e. it can still use the local variables etc of the method which created it, even after that method has finished executing.

In essence, a closure is a code block that can be executed later, but it still maintains its first environment (Execution context) when it is created) -that is, it can still use the local variables in the method for creating it, even if the method has been executed.

This paragraph cannot be regarded as a definition accurately, but the image is described. No absolute definition is provided here. This is described on the wiki.

  

C # closures are usually implemented through anonymous functions and lamada expressions.

 

Let's look at a simple example:

 

var values = new List<int> { 100, 110, 120 };var funcs = new List<Func<int>>();foreach (var v in values)    funcs.Add(() =>    {        //Console.WriteLine(v);        return v;    });foreach (var f in funcs)    Console.WriteLine(f());Console.WriteLine("{0}{0}", Environment.NewLine);funcs.Clear();for (var i = 0; i < values.Count; i++){   //var v2 = values[i];
   funcs.Add(() =>    {               var v2 = values[i]; //will throw exception 
        return v2;    });}foreach (var f in funcs)    Console.WriteLine(f());
Just a few words
  

Because ()=>v means "return the current value of variable v", not "return the value v was back when the delegate was created",Closures close over variables, not over values.

Because () => v "returnsCurrent Value of variable v"Instead of the return value of "v" when the delegate is created.Closure "variable" instead of closure "value".

Therefore, the added anonymous function in the "for" loop only returns the variable I rather than the value of I. So when f () is actually executed, I is already the value of values. Count, so it throws "out of the index range". Why is foreach okay? Let's look at the header of the closure.

 

History
  

The latter. The C# 1.0 specification actually did not say whether the loop variable was inside or outside the loop body, as it made no observable difference. When closure semantics were introduced in C# 2.0, the choice was made to put the loop variable outside the loop, consistent with the "for" loop.--Eric Lippert

The closure syntax is introduced in C #2.0, and the loop variable is placed out of the loop body. The for and foreach processes are consistent in this respect. However, Microsoft made a "concession" in the use process, and made adjustments to "foreach" in C #5, but did not make any changes to ". The specific changes are as follows:

  

We are taking the breaking change. In C# 5, the loop variable of a foreach will be logically inside the loop, and therefore closures will close over a fresh copy of the variable each time. The "for" loop will not be changed. --Eric Lippert

In C #5, we made a huge adjustment. The temporary loop variables defined in the "foreach" traversal will be logically restricted in the loop, each loop of "foreach" is a copy of the cyclic variable, so that the closure looks closed (no more ). However, the "for" loop is not modified.

Summary

Anonymous functions and Lambda expressions bring many convenient and simple implementations to our programming, such as writing (List. Max (a) => a. Level ). But we need to be aware that there is still a closure behind these two sweets ). This once again tells our technical staff to "know the truth, but also the truth".

 

References

Closing over the loop variable considered harmful

Closing over the loop variable, part two

For Loop result in Overflow with Task. Run or Task. Start

Is there a reason for C #'s reuse of the variable in a foreach?

The Beauty of Closures

Future of Code Reading Notes ,)

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.