Home > Backend Development > C++ > Why do all lambda expressions in a foreach loop capture the same variable instead of their individual values?

Why do all lambda expressions in a foreach loop capture the same variable instead of their individual values?

Patricia Arquette
Release: 2024-10-28 22:16:30
Original
456 people have browsed it

Why do all lambda expressions in a foreach loop capture the same variable instead of their individual values?

Captured Variables in Lambda Expressions: Demystifying the "foreach Loop Variable" Mystery

Consider the perplexing code below, which aims to create a list of methods that greet various data types:

public class MyClass
{
    public delegate string PrintHelloType(string greeting);

    public void Execute()
    {
        Type[] types = new Type[]{typeof(string), typeof(float), typeof(int)};
        List<PrintHelloType> helloMethods = new List<PrintHelloType>();

        foreach (var type in types) {
            var sayHello = new PrintHelloType(greeting => SayGreetingToType(type, greeting));
            helloMethods.Add(sayHello);
        }

        foreach (var helloMethod in helloMethods) {
            Console.WriteLine(helloMethod("Hi"));
        }
    }

    public string SayGreetingToType(Type type, string greetingText) {
        return greetingText + " " + type.Name;
    }
}
Copy after login

However, when you run this code, you encounter an unexpected result: it prints "Hi Int32" thrice, instead of the intended "Hi String", "Hi Single", "Hi Int32". What's going on here?

The Subtlety of Closures and Captured Variables

The key to understanding this behavior lies in the concept of closures and captured variables. When a lambda expression is created, it captures the variables from its surrounding scope. In this case, the lambda expression captures the type variable from the foreach loop.

Captured Loop Variables: A Pitfall

Crucially, the captured variable is not the value of type, but the variable itself. As the loop progresses, the type variable changes, while the lambda expressions still refer to the same captured variable.

Correcting the Issue

To achieve the intended behavior, it is necessary to create a new variable within the loop to capture the intended value. Here's how to modify the code:

foreach (var type in types) {
   var newType = type;
   var sayHello = new PrintHelloType(greeting => SayGreetingToType(newType, greeting));
   helloMethods.Add(sayHello);
}
Copy after login

By capturing newType instead of type, the lambda expressions now have a constant reference to the intended value, and the expected output is obtained.

Conclusion

Understanding the intricacies of closures and captured variables is essential when working with lambda expressions. By being mindful of these mechanics, you can avoid unexpected behaviors and ensure your code operates as intended.

The above is the detailed content of Why do all lambda expressions in a foreach loop capture the same variable instead of their individual values?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template