Appel dynamique de fonction - C#/.NET managed - Programmation
Marsh Posté le 27-11-2007 à 10:12:01
ou delegate... (plus clean encore )
Marsh Posté le 28-11-2007 à 09:28:51
ReplyMarsh Posté le 29-11-2007 à 00:50:52
hal9100 a écrit : Bonjour, |
Marsh Posté le 29-11-2007 à 10:28:54
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 :
|
Et quelque part, tu as un code :
Code :
|
Marsh Posté le 30-11-2007 à 00:07:20
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.
Marsh Posté le 30-11-2007 à 14:03:22
Je trouve quand mêmme plus simple de faire ça...
Code :
|
Ensuite t'as juste à faire :
Code :
|
(ça rejoint le "virtual", sauf que je passe par une interface)
Marsh Posté le 30-11-2007 à 15:13:16
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 ?"
Marsh Posté le 30-11-2007 à 16:36:37
Xas a écrit : J'ai du mal a comprendre ta réponse ou celle du "virtual". |
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
Marsh Posté le 30-11-2007 à 21:20:57
ReplyMarsh Posté le 03-12-2007 à 10:00:25
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 :
|
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 , il est même possible de "Cumuler" les appels de fonction avec quelque chose du style:
Code :
|
Ensuite, je suis parfaitement d'accord avec Magibuzz sur ce point :
Citation : |
Marsh Posté le 03-12-2007 à 10:22:36
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.
Marsh Posté le 03-12-2007 à 10:50:37
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...
Marsh Posté le 03-12-2007 à 11:24:06
Xas a écrit : Etant fanboy de la reflection, je m'incline devant la solution de ixemul, plus intéressante. |
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".
Marsh Posté le 03-12-2007 à 11:25:47
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 :
|
=> Ca appelle la fonction qui a le nom de "$fctname".
Marsh Posté le 03-12-2007 à 12:42:22
Xas a écrit : Etant fanboy de la reflection, je m'incline devant la solution de ixemul, plus intéressante. |
Ha mais moi aussi je suis un fan de la reflexion, mais je prefere l'utiliser pour des algos un peu plus obscurs
Marsh Posté le 05-12-2007 à 12:55:20
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.
Marsh Posté le 16-11-2007 à 15:53:53
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)