Heim  >  Artikel  >  Backend-Entwicklung  >  Warum erfasst ein Lambda-Ausdruck innerhalb einer Foreach-Schleife den letzten Wert der Schleifenvariablen?

Warum erfasst ein Lambda-Ausdruck innerhalb einer Foreach-Schleife den letzten Wert der Schleifenvariablen?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-01 00:01:28341Durchsuche

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

Fehlgeschlagener Lambda-Ausdruck in Foreach-Schleife

Betrachten Sie den folgenden Code, der eine Liste von Delegaten initialisiert, von denen jeder eine Methode SayGreetingToType mit einem bestimmten Typ und einer bestimmten Begrüßung aufruft:

<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>

Beim Ausführen dieses Codes würden Sie Folgendes erwarten:

Hi String
Hi Single
Hi Int32

Aufgrund des Abschlussverhaltens wird jedoch der letzte Typ im Typenarray, Int32, von allen Lambda erfasst Ausdrücke. Infolgedessen rufen alle Delegaten SayGreetingToType mit demselben Typ auf, was zur unerwarteten Ausgabe von Folgendem führt:

Hi Int32
Hi Int32
Hi Int32

Die Lösung

Um dieses Problem zu lösen, müssen wir um den Wert der Schleifenvariablen innerhalb des Lambda-Ausdrucks anstelle der Variablen selbst zu erfassen:

<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>

Diese Änderung stellt sicher, dass jeder Lambda-Ausdruck eine eigene Kopie des Typs hat, sodass er SayGreetingToType mit dem richtigen Aufruf aufrufen kann Typargument.

Das obige ist der detaillierte Inhalt vonWarum erfasst ein Lambda-Ausdruck innerhalb einer Foreach-Schleife den letzten Wert der Schleifenvariablen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn