1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Lexikon
  • Erweiterte Suche
  1. Informatik Forum
  2. Webmaster & Internet
  3. Entwicklung

Interessanter C# Bug?

  • Exor
  • 23. Januar 2011 um 21:33
  • Unerledigt
  • Exor
    2
    Exor
    Mitglied
    Punkte
    20
    Beiträge
    2
    • 23. Januar 2011 um 21:33
    • #1

    Hallo,

    ich bin grad auf folgenden Bug? gestoßen

    Code
    List<Func<int>> doublers = new List<Func<int>>();
    
    
                for(int i=0;i<5;i++)
                    doublers.Add( () => i * 2 );
    
    
                foreach (Func<int> f in doublers)
                    Console.WriteLine( f() );
    
    
                Console.ReadKey();
    Alles anzeigen

    gibt aus:

    Code
    10
    10
    10
    10
    10

    Nun ich kann mir denken das, das daran liegt das lambda expressions zur compile time erzeugt werden..

    Allerdings bin ich absolut unfähig die Spezifikation dazu zu finden.

    help?

  • Plantschkuh!
    24
    Plantschkuh!
    Mitglied
    Reaktionen
    163
    Punkte
    6.173
    Beiträge
    1.181
    • 23. Januar 2011 um 22:31
    • #2

    Hmm, Bug... Ich würds eher die Ineleganz, die man bei Sprachen mit destruktivem Update nunmal hat, nennen. Die erzeugten Funktionen sind wohl alle unterschiedliche Objekte, haben aber alle eine Referenz aufs selbe Objekt i. Zu dem Zeitpunkt, zu dem sie aufgerufen werden, hat dieses eine Objekt nunmal den Wert 5.

    Ohne C# zu kennen oder mich irgendwie informiert zu haben: Was passiert, wenn du sowas in die Richtung probierst? Die Idee wär, über die zusätzliche Indirektion den Wert von i zu kopieren, nicht die Adresse. Und zwar zu dem Zeitpunkt, zu dem die Funktion in die Liste eingefügt wird, d.h. mit unterschiedlichen i-Werten.

    Code
    doublers.Add( ((int j) => (() => j * 2))(i) );

    *plantsch*

  • Ringding
    11
    Ringding
    Mitglied
    Reaktionen
    12
    Punkte
    1.237
    Beiträge
    244
    • 23. Januar 2011 um 23:08
    • #3

    Plantschkuh hat recht, closures funktionieren in vielen Sprachen so. Definitiv sagen kann ich es von Python, dort wird das Ergebnis genau gleich sein.

  • fabs
    10
    fabs
    Mitglied
    Reaktionen
    41
    Punkte
    1.046
    Beiträge
    197
    • 24. Januar 2011 um 08:52
    • #4
    Zitat von Plantschkuh!
    Code
    doublers.Add( ((int j) => (() => j * 2))(i) );


    Sollte funktionieren, eine verständlichere Version wäre aber:

    Code
    for(int i=0;i<5;i++)
    {
     int j=i;
            doublers.Add( () => j * 2 );
    }
  • damike
    8
    damike
    Mitglied
    Reaktionen
    11
    Punkte
    681
    Beiträge
    111
    • 25. Januar 2011 um 10:06
    • #5

    Such mal nach "Deferred Execution" und "Lazy Evaluation" - gibt einige MS Artikel dazu

    LG

  • Maximilian Rupp 27. Dezember 2024 um 00:26

    Hat das Thema aus dem Forum Programmieren nach Entwicklung verschoben.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Rechtliches

Impressum

Datenschutzerklärung