Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1667 connectés 

  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  Appel dynamique de fonction

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Appel dynamique de fonction

n°1644056
hal9100
Posté le 16-11-2007 à 15:53:53  profilanswer
 

Bonjour,
 
Dans un script C#, j'aimerais pouvoir appeler dynamiquement une fonction c'est à dire, que la fonction qui sera appelée dépendra d'une variable. Est-ce que c'est possible et si oui, je fais comment ?
 
Exemple :
private void fonction_principale() {
fonction_[variable]() // si la variable vaut titi je lance fonction_titi, si la variable vaut toto je lance fonction_toto
}
private void fonction_titi () {
}
private void fonction_toto () {
}
 
(merci d'avance)

mood
Publicité
Posté le 16-11-2007 à 15:53:53  profilanswer
 

n°1644066
Taz
bisounours-codeur
Posté le 16-11-2007 à 16:03:28  profilanswer
 

virtual

n°1647846
hal9100
Posté le 23-11-2007 à 11:49:45  profilanswer
 

what ?

n°1647868
Taz
bisounours-codeur
Posté le 23-11-2007 à 12:16:08  profilanswer
 

STFW

n°1649345
ixemul
Nan mais sans blague ! ⚡
Posté le 27-11-2007 à 10:12:01  profilanswer
 

ou delegate... (plus clean encore :p)


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°1650028
Taz
bisounours-codeur
Posté le 28-11-2007 à 09:28:51  profilanswer
 

ixemul a écrit :

ou delegate... (plus clean encore :p)


ou pas

n°1650617
compilateu​r_C
Posté le 29-11-2007 à 00:50:52  profilanswer
 

hal9100 a écrit :

Bonjour,
 
je ne comprend pas votre message mais a partir de ce que j'ai lit je peut donne une reponse :
 
private void fonction_principale( char *Mot) {  
(Mot=="titi" )?fonction_titi():fonction_toto(); // avec le mot Mot prendre "titi" ou une autre chaine.
}  
private void fonction_titi () {  
}  
private void fonction_toto () {  
}  
 
 
(merci d'avance)


n°1650678
Xas
Freshershist
Posté le 29-11-2007 à 10:28:54  profilanswer
 

Il demande pas plutot la Reflection ?
 
Edit : Ha je savais que j'avais ça quelque part...
Le problème avec la solution de compilateur_c, c'est le jour où tu rajoutes une 3eme méthode...
Au moins, là, tu restes assez indépendant de l'évolution de ton code appelant.
 

Code :
  1. using System.Reflection;
  2. public class TestReflection
  3. {
  4.  public TestReflection()
  5.  {
  6.  }
  7.  // Méthode qui va choisir quelle fonction tu veux appeler
  8.  public string AppelMethode(string strParam)
  9.  {
  10.   // On récupère le Type de la classe elle-même
  11.   Type oType = this.GetType();
  12.   string strMask = "Appel_";
  13.   // On va récupérer la liste des méthodes qui existent dans la classe 'TestReflection'
  14.   MethodInfo[] ListMethods = oType.GetMethods();
  15.   object objVal = null;
  16.   // Donc pour chaque méthode :
  17.   foreach ( MethodInfo mi in ListMethods )
  18.   {
  19.    // Si le nom de la méthode est égale à "Appel_" + strPAram
  20.    if ( mi.Name.ToUpper().Equals(strMask.ToUpper() + strParam.ToUpper() ) )
  21.    {
  22.     // Alors on 'exécute' cette méthode que l'on a trouvée
  23.     // On sait qu'elle retourne "quelqu'chose". Donc on récupère ce quelque chose
  24.     objVal = mi.Invoke(this, null);
  25.     // On sort de la boucle foreach
  26.     break;
  27.    }
  28.   }
  29.   // Si on a rien trouvé, parce que objVal est resté null
  30.   // Tu fais ce que tu veux. Moi j'exceptionne.
  31.   if ( objVal == null )
  32.    throw new Exception("C'est la fin du monde..." );
  33.   // Sinon, ben je retourne la valeur string du résultat
  34.   return objVal.ToString();
  35.  }
  36.  public string Appel_Non()
  37.  {
  38.   return "NON";
  39.  }
  40.  public string Appel_Oui()
  41.  {
  42.   return "OUI";
  43.  }


 
Et quelque part, tu as un code :

Code :
  1. ...
  2. TestReflection tr = new TestReflection();
  3. ...
  4. switch ( qqch à vérifier )
  5. {
  6.     case 1:
  7.         tr.AppelMethode("Oui" );
  8.         break;
  9.     case 2:
  10.         tr.AppelMethode("Non" );
  11.         break;
  12.     default:
  13.         tr.AppelMethode("Oui" );
  14.         break;
  15. }


Message édité par Xas le 29-11-2007 à 23:42:41
n°1650806
Taz
bisounours-codeur
Posté le 29-11-2007 à 14:03:48  profilanswer
 

Belle usine à gaz, très bon conseil pour un débutant.

n°1651207
Xas
Freshershist
Posté le 30-11-2007 à 00:07:20  profilanswer
 

Voilà, j'ai réediter, et j'ai mis des commentaires, et un exemple d'utilisation.
Usine à gaz ? La vache, je suis vexé sur ce coup. Une seule méthode avec un seul foreach...
 
Le mec veut appeller dynamiquement une méthode. C'est, à mon avis, une des meilleures solutions. Propre, facilement maintenable, et un bon début pour comprendre la reflection .NET.
 
Maintenant, si sous pretexte qu'il est débutant, on va lui filer une solution de merde, c'est vraiment n'importe quoi.
 
On lui offre une bonne solution pour son problème.
C'est aussi à lui de faire des efforts pour comprendre. La science .NET et programmation, ça tombe pas dessus. Faut travailler.
On est pas ici juste pour donner le code qui va fonctionner, et puis c'est tout, merci, au revoir. Si ? Ha bah désolé, je me suis trompé d'endroit, je ne dirais plus rien.
Qu'il reste ignorant, alors.


Message édité par Xas le 30-11-2007 à 00:07:32
mood
Publicité
Posté le 30-11-2007 à 00:07:20  profilanswer
 

n°1651326
MagicBuzz
Posté le 30-11-2007 à 14:03:22  profilanswer
 

Je trouve quand mêmme plus simple de faire ça...
 

Code :
  1. public interface ITruc
  2. {
  3.    void FaireQuelqueChose();
  4. }
  5.  
  6. public static class Truc
  7. {
  8.   ITruc CreateTruc(string value)
  9.   {
  10.      switch (value)
  11.      {
  12.         case "titi":
  13.            return new Titi();
  14.         case "toto":
  15.            return new Toto();
  16.         default:
  17.            throw new Exception("Paramètre incorrect" );
  18.      }
  19.    }
  20. }
  21.  
  22. public class Titi : ITruc
  23. {
  24.   private string msg = "Titi";
  25.  
  26.   public Titi()
  27.   {
  28.      // Construteur
  29.   }
  30.  
  31.   public void FaireUnTruc()
  32.   {
  33.      Console.WriteLine(msg);
  34.   }
  35. }
  36.  
  37. public class Toto : ITruc
  38. {
  39.   private string msg = "Toto";
  40.  
  41.   public Toto()
  42.   {
  43.      // Construteur
  44.   }
  45.  
  46.   public void FaireUnTruc()
  47.   {
  48.      for (int i = 0; i < 10; i++)
  49.      {
  50.         Console.WriteLine(string.Format("{0} - {1}", msg, i);
  51.      }
  52.   }
  53. }


 
Ensuite t'as juste à faire :
 

Code :
  1. ITruc t1, t2;
  2.  
  3. t1 = Truc.CreateTruc("toto" );
  4. t2 = Truc.CreateTruc("titi" );
  5.  
  6. t1.FaireUnTruc();
  7. t2.FaireUnTruc();


 
(ça rejoint le "virtual", sauf que je passe par une interface)


Message édité par MagicBuzz le 30-11-2007 à 14:04:03
n°1651367
Xas
Freshershist
Posté le 30-11-2007 à 15:13:16  profilanswer
 

J'ai du mal a comprendre ta réponse ou celle du "virtual".
De la maniere dont j'ai lu la question de hal, il a un soucis d'appel sur une liste de méthode qui ont le même préfixe. L'appel à la bonne méthode dépend du suffixe "en test".
 
Du coup je vois très mal en quoi ta solution est plus simple (je ne dis pas qu'elle est mauvaise, là je parle de simplicité)
 
Si je suis allé trop loin dans mon interpréation, alors la question serait tout simplement "j'ai plusieurs fonctions, comment je fais pour en appeller une ou l'autre suivant un test ?"


---------------
H. - 48h en fiat et j'ai déjà perdu la maitrise de mon argent
n°1651465
MagicBuzz
Posté le 30-11-2007 à 16:36:37  profilanswer
 

Xas a écrit :

J'ai du mal a comprendre ta réponse ou celle du "virtual".
De la maniere dont j'ai lu la question de hal, il a un soucis d'appel sur une liste de méthode qui ont le même préfixe. L'appel à la bonne méthode dépend du suffixe "en test".
 
Du coup je vois très mal en quoi ta solution est plus simple (je ne dis pas qu'elle est mauvaise, là je parle de simplicité)
 
Si je suis allé trop loin dans mon interpréation, alors la question serait tout simplement "j'ai plusieurs fonctions, comment je fais pour en appeller une ou l'autre suivant un test ?"


Je pense que c'est nous qui sommes allé plus loin que toi dans l'analyse de la question ;)
 
En gros, Hal veut fait un truc pourri directement hérité de PHP ou JS.
Le genre de truc qui est plantogène et piratogène à souhait.
 
Le but du jeu ici, c'est en fonction d'un paramètre, lancer une fonction spécifique, dans un cadre commun.
 
Le fait de créer une interface et des classes dérivées (ou une classe générique avec une méthode virtuelle, et des classes qui redéfinissent cette méthode) permet dont de produit le même effet : on instancie différentes classe héritées selon le critère en question, et on ne les manipule que via une déclaration de l'interface/classe générique, et on appelle la méthode de base, dont le comportement est surchargé au niveau de la classe fille, qui dépend du paramètre.
 
Ceci ne répond donc pas réellement à la question initiale, mais donne un moyen propre d'obtenir le même résultat.
 
Genre tu me demandes dans quel direction est New York. Moi je te colle dans un RER en destination de Charles de Guaule pour que tu prennes un avion. Je peux te dire que c'est à l'ouest sans t'indiquer qu'il y a un océan à traverser, mais ce serait criminel... Là c'est pareil ;)

n°1651576
dkomputer
Posté le 30-11-2007 à 21:20:57  profilanswer
 

Je plussoie sur le fait que la reflection semble la meilleure piste

n°1651990
ixemul
Nan mais sans blague ! ⚡
Posté le 03-12-2007 à 10:00:25  profilanswer
 

dkomputer a écrit :

Je plussoie sur le fait que la reflection semble la meilleure piste


 
Non...  
 
Absolument pas...
 
La refelxion est beaucoup trop dangereuse
 
La solution avec delegate, qui rappelons le est exactement définie pour ce genre de chose est plus simple, totalement protégée des effets de bords et beaucoup plus souple:
 

Code :
  1. private delegate void appelFonction();
  2. private appelFonction  func;
  3. public void dispatch(string v)
  4. {
  5.   switch(v)
  6.   {
  7.     case "Toto":
  8.       func = new appelFonction(toto);
  9.       break;
  10.     case "Titi":
  11.       func = new appelFonction(titi);
  12.       break;
  13.     default:
  14.       throw new Exception("Fonction inexistante" );
  15.   }
  16.   func();
  17. }
  18. private void toto()
  19. {
  20.   Console.WriteLine("toto" );
  21. }
  22. private void titi()
  23. {
  24.   Console.WriteLine("titi" );
  25. }


 
Piqure de rappel, les delegate peuvent être assimilés à des pointeurs sur fonctions, ce qui, le cas présent permet de définir sur quel fonction notre delegate pourra pointer.
 
Astuce [:icon3], il est même possible de "Cumuler" les appels de fonction avec quelque chose du style:
 

Code :
  1. func = new appelFonction(toto);
  2. func += new appelFonction(titi);
  3. func();


 
 
Ensuite, je suis parfaitement d'accord avec Magibuzz sur ce point :
 
 

Citation :


En gros, Hal veut fait un truc pourri directement hérité de PHP ou JS.  
Le genre de truc qui est plantogène et piratogène à souhait.  
 


Message édité par ixemul le 03-12-2007 à 10:02:00

---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°1652009
MagicBuzz
Posté le 03-12-2007 à 10:22:36  profilanswer
 

Grmpf.
 
Ah oui, j'avais complètement oublié cette méthode.
Effectivement, c'est à 100% mieux que virtual/interface. Ca se rapproche du fonctionnement des méthodes utilisant la réflexion, mais de façon propre : on sait à l'avance comment ça va se comporter, ce qui n'est pas le cas avec la réflection. :jap:

n°1652029
Xas
Freshershist
Posté le 03-12-2007 à 10:50:37  profilanswer
 

Etant fanboy de la reflection, je m'incline devant la solution de ixemul, plus intéressante.
Mais je reste dubitatif sur la dernière affirmation de MagicBuzz..
 
Sinon j'aurais du faire du php dans le passé, vu que je suis le seul à pas avoir compris de quoi s'inspire hal...

Message cité 3 fois
Message édité par Xas le 03-12-2007 à 10:50:46
n°1652058
MagicBuzz
Posté le 03-12-2007 à 11:24:06  profilanswer
 

Xas a écrit :

Etant fanboy de la reflection, je m'incline devant la solution de ixemul, plus intéressante.
Mais je reste dubitatif sur la dernière affirmation de MagicBuzz..


 
Tu crées une fonction "Appel_truc", sans chercher à savoir si elle est nommée "truc", "Appel_truc" ou "machin_chose".
Genre tu fais de la TMA et t'as autrechose à foutre que de relire 25 Mo de code pour savoir si créer une méthode risque de tout foutre par terre (puisque dans du code bien écrit, c'est pas cencé)
 
Maintenant, avec ton exemple, tu appelles "AppelFunction" en passant "truc" en paramètre.
Et zou ! Ca te lance ta nouvelle méthode.
Mais t'avait pas forcément envie de pouvoir la lancer de la sorte... Donc ni toi aujourd'hui qui écrit le code, ni le gars qui repasse derrière, ne peuvent prévoir tous les effets de bord de ton code. Et pire, c'est avec ce genre de code qu'on trouve dses exploit.
 
Par exemple, si j'appelle "AppelFunction" non pas avec "Truc", mais "@@@@@@FonctionDangereuse" avec les "@" un caractère utilisant une exploit qui va effectuer un "backspace" lors d'une concaténation de chaîne, alors je peux lancer "FonctionDangereuse" malgré ton test. Y'a pas à tortiller, c'est dangereux... Et ça, tant qu'un exploit n'aura pas été trouvé, tu seras incapable de prévoir ton code.
 
Avec le delegate, tout ces trucs ne peuvent pas arriver.
Le seul "hack" possible, c'est d'aller modifier le code compilé afin de modifier les valeurs des pointeurs sur toto et titi afin de lancer d'autres fonction.
Mais sans ça, aucune exploit n'est utilisable pour, et tout modification de code reste sous contrôle : c'est pas parceque je crée une fonction "truc" que j'ai un risque d'avoir ma fonction appelée "par le saint esprit".


Message édité par MagicBuzz le 03-12-2007 à 11:26:37
n°1652062
MagicBuzz
Posté le 03-12-2007 à 11:25:47  profilanswer
 

Xas a écrit :

Sinon j'aurais du faire du php dans le passé, vu que je suis le seul à pas avoir compris de quoi s'inspire hal...


 
Ben en PHP tu peux faire un truc du genre (syntaxe mise à part) :
 

Code :
  1. function AppelFct($fctname)
  2. {
  3.     $$fctname();
  4. }


=> Ca appelle la fonction qui a le nom de "$fctname".
 


Message édité par MagicBuzz le 03-12-2007 à 11:26:23
n°1652121
ixemul
Nan mais sans blague ! ⚡
Posté le 03-12-2007 à 12:42:22  profilanswer
 

Xas a écrit :

Etant fanboy de la reflection, je m'incline devant la solution de ixemul, plus intéressante.
Mais je reste dubitatif sur la dernière affirmation de MagicBuzz..
 
Sinon j'aurais du faire du php dans le passé, vu que je suis le seul à pas avoir compris de quoi s'inspire hal...


 
Ha mais moi aussi je suis un fan de la reflexion, mais je prefere l'utiliser pour des algos un peu plus obscurs [:rhetorie du chaos]


---------------
VA APPRENDRE ET REVIENS QUAND TU SAIS, SINON ABSTIENT TOI C'EST UN GRAND CONSEIL QUE JE TE DONNE... TU ES INCOMPÉTENT ET C'EST UNE RÉALITÉ, TU N'AS RIEN A FAIRE ICI FAUT S'Y CONNAITRE ... -Jojo1998 - RIP - http://tinyurl.com/qc47ftk
n°1653220
hal9100
Posté le 05-12-2007 à 12:55:20  profilanswer
 

Merci de vous être acharnés à ce point sur mon problème, ça fait plaisir de se sentir épaulé dans la détresse.
 
L'ennui c'est qu'avec les kilos de code que je bricole tous les jours, je sais même plus pour quelle raison j'avais posé cette question.

n°1653221
hal9100
Posté le 05-12-2007 à 12:56:19  profilanswer
 

Mais je vais retrouver

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  Appel dynamique de fonction

 

Sujets relatifs
executer une fonction dont le nom est dans une variableC++ fonction qui repere les alphanumériques et les accents
[PHP/MySQL] Calcul d'un prix en fonction d'une dimensionStatistiques une fonction me manque
specialisation partielle d'une fonction d'un patron de classe[AS] Typo dynamique, unicode, inserer des caracteres... problème !
définir un polynome à l'aide de la fonction "atoi" avec des listesBBCode fonction [spoil]
mail, PJ et free: si qqun a reussi... [RESOLU]Appel dynamique à une fonction ou sub
Plus de sujets relatifs à : Appel dynamique de fonction


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR