IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Delegate dans une boucle


Sujet :

C#

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    juin 2008
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : juin 2008
    Messages : 608
    Points : 1 048
    Points
    1 048
    Par défaut Delegate dans une boucle
    Salut
    ------

    Quelqu'un peut-il me dire pourquoi si j'écris:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      for (int i = 0; i < 3; i++)
    {
        myTimers[i] = new Timer(100);
        myTimers[i].Elapsed += delegate { TimerSweepElapsed(i); };
    }
    Alors toutes mes entrées dans TimerSweepElapsed pour mes 3 timers arrivent avec la valeur "3", soit la valeur de sortie de i de la boucle?

    Alors que si j'écris de façon qui semble idiote ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      for (int i = 0; i < 3; i++)
    {
        myTimers[i] = new Timer(100);
        var param = i;
        myTimers[i].Elapsed += delegate { TimerSweepElapsed(param); };
    }
    Je reçois bien une valeur comprise entre 0 et 2.

    J'ai déjà constaté que je devais procéder comme ça, mais j'aimerais connaître la bonne raison, ou savoir s'il n'y a pas une méthode plus élégante.
    Merci d'avance,
    Claude

  2. #2
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    avril 2007
    Messages
    14 025
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : avril 2007
    Messages : 14 025
    Points : 24 810
    Points
    24 810
    Par défaut
    dans le 1er cas le délégué pointe sur la variable i dans tous les cas, qui change plusieurs fois de valeur certes mais vaut 3 à la fin

    dans le 2ème cas le délégué pointe vers une nouvelle variable à chaque tour, qui a la bonne valeur car chaque tour à sa propre variable
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    juin 2008
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : juin 2008
    Messages : 608
    Points : 1 048
    Points
    1 048
    Par défaut
    Merci
    Donc, en fait, malgré que int soit supposé être passé par valeur, ici c'est passé par référence?
    C'est ce que j'avais cru constater, mais il y a une raison spécifique?

  4. #4
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    juillet 2016
    Messages
    2 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juillet 2016
    Messages : 2 690
    Points : 10 498
    Points
    10 498
    Billets dans le blog
    21
    Par défaut
    C'est effectivement une question de porté des variables.

    Un lambda capture bien une référence et non une valeur (qu'importe le type sous-jacent, il va être boxé si nécessaire), car il faut bien distinguer la déclaration de la lambda de son exécution.

    Au sein de la lambda, les paramètres sont évalués à l'exécution de la lambda, pas au moment de sa déclaration. C'est le comportement normal et voulu. La puissance d'une lambda est de permettre de faire une méthode anonyme dont certains paramètres sont issus du contexte même (comprendre: les variables à porté). C'est d'autant plus puissant que le contexte est évalué au moment de l'exécution de la lambda, pas au moment de sa déclaration. Mais pour que cette évaluation puisse se faire à l'exécution, il faut obligatoirement une référence sur les variables, y compris pour les types valeurs.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    juin 2008
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : juin 2008
    Messages : 608
    Points : 1 048
    Points
    1 048
    Par défaut
    Merci pour cette réponse parfaitement complète.
    Ça veut donc dire au final que le fait de procéder comme je l'ai fait maintient en vie tout au long de l'application une classe juste pour englober ma variable pour chaque itération de boucle, et avec un unboxing implicite à chaque appel.
    Ce n'est pas très efficient (même si on ne parle que de fifrelins). J'ai plutôt intérêt à écrire 3 fois la ligne avec un passage de constante 0,1,2

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [langage] incrementation de variable dans une boucle
    Par mimilou dans le forum Langage
    Réponses: 15
    Dernier message: 16/04/2004, 13h23
  2. Problème avec TNMSMTP dans une boucle.
    Par Orgied dans le forum Web & réseau
    Réponses: 3
    Dernier message: 07/04/2004, 10h19
  3. swf dans une boucle asp
    Par Chucky69 dans le forum Flash
    Réponses: 11
    Dernier message: 10/02/2004, 17h07
  4. [Vb.net] Indexé un objet crée dans une boucle
    Par picpic dans le forum Windows Forms
    Réponses: 10
    Dernier message: 17/12/2003, 14h37
  5. Pause dans une boucle
    Par HT dans le forum Langage
    Réponses: 4
    Dernier message: 03/06/2003, 08h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo