> 백엔드 개발 > C++ > 본문

Foreach 루프 내부의 람다 표현식이 루프 변수의 마지막 값을 캡처하는 이유는 무엇입니까?

Mary-Kate Olsen
풀어 주다: 2024-11-01 00:01:28
원래의
407명이 탐색했습니다.

Why does a Lambda Expression inside a Foreach Loop capture the last value of the loop variable?

Foreach 루프에서 실패한 람다 표현식

각각 특정 유형과 인사말을 사용하여 SayGreetingToType 메서드를 호출하는 대리자 목록을 초기화하는 다음 코드를 고려하세요. 🎜>

<code class="csharp">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)
        {
            // Initialize the lambda expression with the captured variable 'type'
            var sayHello = new PrintHelloType(greeting => SayGreetingToType(type, greeting));
            helloMethods.Add(sayHello);
        }

        // Call the delegates with the greeting "Hi"
        foreach (var helloMethod in helloMethods)
        {
            Console.WriteLine(helloMethod("Hi"));
        }
    }

    public string SayGreetingToType(Type type, string greetingText)
    {
        return greetingText + " " + type.Name;
    }
}</code>
로그인 후 복사
이 코드를 실행하면 다음이 표시될 것으로 예상됩니다.

Hi String
Hi Single
Hi Int32
로그인 후 복사
그러나 클로저 동작으로 인해 유형 배열의 마지막 유형인 Int32가 모든 람다에 의해 캡처됩니다. 표현. 결과적으로 모든 대리자가 동일한 유형으로 SayGreetingToType을 호출하여 다음과 같은 예상치 못한 출력이 발생합니다.

Hi Int32
Hi Int32
Hi Int32
로그인 후 복사

해결책

이 문제를 해결하려면 다음이 필요합니다. 변수 자체 대신 람다 표현식 내에서 루프 변수의 값을 캡처하려면:

<code class="csharp">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)
        {
            // Capture a copy of the current 'type' value using a new variable
            var newType = type;

            // Initialize the lambda expression with the new variable 'newType'
            var sayHello = new PrintHelloType(greeting => SayGreetingToType(newType, greeting));
            helloMethods.Add(sayHello);
        }

        // Call the delegates with the greeting "Hi"
        foreach (var helloMethod in helloMethods)
        {
            Console.WriteLine(helloMethod("Hi"));
        }
    }

    public string SayGreetingToType(Type type, string greetingText)
    {
        return greetingText + " " + type.Name;
    }
}</code>
로그인 후 복사
이 수정을 통해 각 람다 표현식에는 해당 유형의 자체 복사본이 있으므로 올바른 형식으로 SayGreetingToType을 호출할 수 있습니다. 유형 인수입니다.

위 내용은 Foreach 루프 내부의 람다 표현식이 루프 변수의 마지막 값을 캡처하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿