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 et redondance de code


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 69
    Par défaut delegate et redondance de code
    Bonjour,

    J'ai un liste d'objets (de type A) et je veux pour chaque elements lui faire executer la fonction f1, f2 ou f3 (la même pour touts les elements de la liste).

    Une manière de faire ça pourrait etre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public void doF1OnAll()
        {
            //parcourt de la liste et pour chaque element elemnt.f1();
        }
    + les fonctions doF2OnAll() et doF3OnAll()

    Mais c'est quand meme pas super, on fait presque toujours la meme chose et pourtant on est obliger de dupliquer le code.

    J' ai pensé aux delegates mais je ne suis pas encore arrivé à faire exactement ce que je veux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    public class A {
        public void f1(){}
        public void f2(){}
        public void f3(){}
    }
     
    public class B {
        Queue maQueueA;//queue contenant des objets de type A
        public delegate void myDelegate(A objA );
     
        public void toto()
        {
             forAll(callF1OnA);
        }
     
         private void callF1OnA(AobjA)
        {
             objA.f1();
         }
     
        private void forAll(myDelegate aFunc)
        {
             Queue copy = new Queue(maQueueA);
             while (copy.Count > 0) //execution de aFunc sur chaque element de la liste
              aFunc( ((A) copy.Dequeue()));
     
        }
    }
    Maintenant le parcours de la liste est codé une unique fois mais je dois passer par une fonction intermédiaire (callF1OnA).

    Bon en résumé, voila ce que je voudrais pouvoir faire :

    avoir une fonction
    qui prenne en paramtre soit la fonction f1, soit f2, soit f3 et l'exécute sur chaque element A de la liste. Ainsi de la meme maniere, si je voudrai iniialiser tous les elements de la liste je n'aurais qu'à faire forALL(init()), où init est une fonction non static de la classe A.

    Est ce que des gens ont des idées ?

    PS : je n'ai surement pas été très clair alors n'hésitez pas à poser des questions

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2006
    Messages : 15
    Par défaut Voilà
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Collections;
     
    namespace ConsoleApplication13
    {
        public class Program
        {
            static void Main(string[] args)
            {
                Queue<A> q = new Queue<A>();
     
                q.Enqueue(new A());
                q.Enqueue(new A());
                q.Enqueue(new A());
     
                foreach (A a in q)
                {
                    CallFunction(a.Init, a);
                    CallFunction(a.Update, a);
                    CallFunction(a.Print, a);    
                }
     
                Console.ReadLine();        
            }
     
            delegate void myDelegate(A a);
     
            static void CallFunction(myDelegate d, A a)
            {
                if (d != null)
                {
                    d(a);
                }
            }
        }
     
     
        public class A
        {
            private int id;
     
            public int Id
            {
                get 
                {
                    return id;
                }
                set 
                {
                    id = value;
                }
            }
            #region Fucntions
            public void Init(A a)
            {
                Id = 0;
                Console.WriteLine("A.Id initialized");
            }
            public void Update(A a)
            {
                Id = 5; 
                Console.WriteLine("A.Id Updated");
            }
            public void Print(A a)
            {
                Console.WriteLine("Printing Id = {0}", Id);
            }
            #endregion 
        }
    }
    Ca correspond à ce que tu veux faire ?

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 69
    Par défaut
    En faite là j'aurais toujours la redondance de code si j'ai une autre fonction qui doit faire un traitement sur tous les A.

    J'aurais voulu un truc dans le genre suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    public faireTraitementSurTout(uneFonction)
    {
         foreach (A a in q)
              a.uneFonction() //pas valide...d'ou mon probleme
    }
     
    //le main deviendrais donc :
    static void Main(string[] args)
    {
         Queue<A> q = new Queue<A>();
     
         q.Enqueue(new A());
         q.Enqueue(new A());
         q.Enqueue(new A());
         faireTraitementSurTout(init());
         faireTraitementSurTout(update());
         faireTraitementSurTout(print());
    }
     
    //une autre fonction 
    public void reset()
    {
         faireTraitementSurTout(init());
    }
     
    //encore une fonction
    public void printAll()
    {
         faireTraitementSurTout(print());
    }

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 499
    Par défaut
    Salut,
    si tu dis que ça, ça ne marche pas :

    Citation Envoyé par duaner
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public faireTraitementSurTout(uneFonction)
    {
         foreach (A a in q)
              a.uneFonction() //pas valide...d'ou mon probleme
    }
    pourquoi ne pas faire un enum :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    public enum TYPE_FONCTION {FONCTION1, FONCTION2, FONCTION3};
     
    public faireTraitementSurTout(TYPE_FONCTION LaFonctionAExecuter)
    {
        switch (LaFonctionAExecuter)
        {
            case FONCTION1:
                foreach (A a in q)
                    a.Fonction1(); 
                break;
            case FONCTION2:
                foreach (A a in q)
                    a.Fonction2(); 
                break;
            case FONCTION1:
                foreach (A a in q)
                    a.Fonction3(); 
                break;
        }
    }
    ?...

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    69
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 69
    Par défaut
    @Maniak merci, c'est bien ce que je voulais faire : appeler la même méthode de ma queue pour chaque élément de ma liste. Maintenant faut passer par une liste, ca ne devrait pas poser de problème. Mais c'est vrai que ca aurait été bien que le foreach soit de base dans pour une queue.

    @melleb, en faite c'est justement pour éviter le switch que j'aurais aimer pouvoir passer la fonction à exécuter sur chaque élément de la liste en paramètre ainsi, pas besoin d'énum, ni de switch ...

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    652
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 652
    Par défaut
    Ben si ta collection était de type List<T>, tu pourrais utiliser la méthode ForEach. Ça évite la duplication du foreach.

    Tu peux créer une List<T> à partir d'une Queue<T> donc ça peut toujours se faire. Reste à voir à quel point tu y gagnes par rapport au 'problème' qu'il peut y avoir à écrire foreach plusieurs fois...

    Grosso modo ça donnerait un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    private static void Main()
    {
    	Queue<int> queue = new Queue<int>();
    	List<int> list = new List<int>( queue );
     
    	list.ForEach( f1 );
    	list.ForEach( f2 );
    }
     
    private static void f1( int item )
    {
    	...
    }
     
    private static void f2( int item )
    {
    	...
    }
    La méthode indiquée sera appliquée à chaque élément de la collection.

    Bon après, ça aurait été bien si les méthodes de List<T> (ForEach & co) avaient été ajoutées aux autres classes de collections génériques, mais c'est pas le cas, va savoir pourquoi...

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

Discussions similaires

  1. [XL-2007] Problème redondance de code
    Par luko6 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 16/10/2009, 00h30
  2. Redondance de code entre librairies
    Par DSGSLA dans le forum C++
    Réponses: 2
    Dernier message: 31/08/2009, 10h54
  3. Boucle for pour éviter la redondance de code
    Par zaza85270 dans le forum Langage
    Réponses: 15
    Dernier message: 10/11/2008, 16h19
  4. [HTML]Eviter les redondances de code
    Par Pfeffer dans le forum Balisage (X)HTML et validation W3C
    Réponses: 9
    Dernier message: 30/12/2005, 09h13

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