J'ai plusieurs méthodes toutes avec la même signature (paramètres et valeurs de retour) mais des noms différents et les internes des méthodes sont différents. Je veux transmettre le nom de la méthode à exécuter à une autre méthode qui invoquera la méthode passée.
public int Method1(string)
{
... do something
return myInt;
}
public int Method2(string)
{
... do something different
return myInt;
}
public bool RunTheMethod([Method Name passed in here] myMethodName)
{
... do stuff
int i = myMethodName("My String");
... do more stuff
return true;
}
public bool Test()
{
return RunTheMethod(Method1);
}
Ce code ne fonctionne pas mais c'est ce que j'essaie de faire. Ce que je ne comprends pas, c'est comment écrire le code RunTheMethod car j'ai besoin de définir le paramètre.
Réponses:
Vous pouvez utiliser le délégué Func dans .net 3.5 comme paramètre dans votre méthode RunTheMethod. Le délégué Func vous permet de spécifier une méthode qui prend un certain nombre de paramètres d'un type spécifique et renvoie un seul argument d'un type spécifique. Voici un exemple qui devrait fonctionner:
la source
Action
au lieu deFunc<string, int>
.Action<int,string>
correspond à une méthode qui prend 2 paramètres (int et chaîne) et renvoie void.Func<double,string,int>
correspond à une méthode qui prend 2 paramètres (double
etstring
) et retourneint
. Le dernier type spécifié est le type de retour. Vous pouvez utiliser ce délégué pour jusqu'à 16 paramètres. Si vous en avez besoin, écrivez votre propre délégué en tant quepublic delegate TResult Func<in T1, in T2, (as many arguments as you want), in Tn, out TResult>(T1 arg1, T2 arg2, ..., Tn argn);
. Veuillez me corriger si j'ai mal compris.Vous devez utiliser un délégué . Dans ce cas, toutes vos méthodes prennent un
string
paramètre et renvoient unint
- celui-ci est le plus simplement représenté par leFunc<string, int>
délégué 1 . Ainsi, votre code peut devenir correct avec un changement aussi simple que celui-ci:Certes, les délégués ont beaucoup plus de pouvoir que cela. Par exemple, avec C #, vous pouvez créer un délégué à partir d'une expression lambda , vous pouvez donc invoquer votre méthode de cette façon:
Cela créera une fonction anonyme comme celle-ci:
puis passez ce délégué à la
RunTheMethod
méthode.Vous pouvez utiliser des délégués pour les abonnements aux événements, l'exécution asynchrone, les rappels - toutes sortes de choses. Cela vaut la peine de les lire, surtout si vous souhaitez utiliser LINQ. J'ai un article qui traite principalement des différences entre les délégués et les événements, mais vous pouvez quand même le trouver utile.
1 Ceci est simplement basé sur le
Func<T, TResult>
type de délégué générique dans le cadre; vous pouvez facilement déclarer le vôtre:puis définissez le paramètre de type à la
MyDelegateType
place.la source
public **delegate** int MyDelegateType(string value)
?De l'exemple d'OP:
Vous pouvez essayer Action Delegate! Et puis appelez votre méthode en utilisant
Ou
Appelez ensuite simplement method
la source
InvokeMethod
appel lambda devrait être à laRunTheMethod
placeUsage:
la source
Pour partager une solution aussi complète que possible, je vais finir par présenter trois façons différentes de faire, mais maintenant je vais partir du principe le plus élémentaire.
Une brève introduction
Toutes les langues qui s'exécutent au-dessus de CLR ( Common Language Runtime ), telles que C #, F # et Visual Basic, fonctionnent sous une machine virtuelle, qui exécute le code à un niveau plus élevé que les langues natives comme C et C ++ (qui se compilent directement sur la machine code). Il s'ensuit que les méthodes ne sont pas une sorte de bloc compilé, mais ce ne sont que des éléments structurés que CLR reconnaît. Ainsi, vous ne pouvez pas penser à passer une méthode en tant que paramètre, car les méthodes ne produisent aucune valeur elles-mêmes, car ce ne sont pas des expressions! Ce sont plutôt des instructions, qui sont définies dans le code CIL généré. Ainsi, vous ferez face au concept de délégué.
Qu'est-ce qu'un délégué?
Un délégué représente un pointeur sur une méthode. Comme je l'ai dit ci-dessus, une méthode n'est pas une valeur, donc il y a une classe spéciale dans les langages CLR
Delegate
, qui enveloppe n'importe quelle méthode.Regardez l'exemple suivant:
Trois façons différentes, le même concept derrière:
Méthode 1
Utilisez la
Delegate
classe spéciale directement comme l'exemple ci-dessus. Le problème de cette solution est que votre code ne sera pas contrôlé lorsque vous passerez dynamiquement vos arguments sans les restreindre aux types de ceux de la définition de méthode.Way 2
Outre la
Delegate
classe spéciale, le concept de délégué se propage aux délégués personnalisés, qui sont des définitions de méthodes précédées par ledelegate
mot clé, et ils se comportent de la même manière que les méthodes normales. Ils sont ainsi vérifiés, vous obtiendrez donc un code parfaitement sûr.Voici un exemple:
Méthode 3
Vous pouvez également utiliser un délégué qui a déjà été défini dans la norme .NET:
Action
termine unvoid
sans arguments.Action<T1>
termine unvoid
avec un argument.Action<T1, T2>
termine unvoid
avec deux arguments.Func<TR>
encapsule une fonction avec unTR
type de retour et sans arguments.Func<T1, TR>
encapsule une fonction avec leTR
type de retour et avec un argument.Func<T1, T2, TR>
termine une fonction avecTR
type de retour et avec deux arguments.(Cette dernière solution est celle que la plupart des gens ont publiée.)
la source
Func<T1,T2,TR>
Vous devez utiliser un
Func<string, int>
délégué, qui représente une fonction prenant unstring
argument as et retournant unint
:Ensuite, utilisez-le:
la source
Test
méthode devrait êtrereturn RunTheMethod(Method1);
Si vous voulez pouvoir modifier la méthode qui est appelée au moment de l'exécution, je recommanderais d'utiliser un délégué: http://www.codeproject.com/KB/cs/delegates_step1.aspx
Il vous permettra de créer un objet pour stocker la méthode à appeler et vous pouvez le transmettre à vos autres méthodes lorsque cela est nécessaire.
la source
Bien que la réponse acceptée soit absolument correcte, je voudrais fournir une méthode supplémentaire.
Je me suis retrouvé ici après avoir fait ma propre recherche d'une solution à une question similaire. Je construis un framework piloté par plugin, et dans le cadre de celui-ci, je voulais que les gens puissent ajouter des éléments de menu au menu des applications à une liste générique sans exposer un
Menu
objet réel car le framework peut se déployer sur d'autres plateformes qui n'ont pasMenu
interface utilisateur objets. Ajouter des informations générales sur le menu est assez facile, mais donner au développeur du plugin suffisamment de liberté pour créer le rappel lorsque le menu est cliqué s'est avéré être une douleur. Jusqu'à ce que je me rende compte que j'essayais de réinventer la roue et l'appel des menus normaux et déclencher le rappel des événements!Donc, la solution, aussi simple que cela puisse paraître une fois que vous vous en rendez compte, m'a échappé jusqu'à présent.
Créez simplement des classes distinctes pour chacune de vos méthodes actuelles, héritées d'une base si vous le souhaitez, et ajoutez simplement un gestionnaire d'événements à chacune.
la source
Voici un exemple qui peut vous aider à mieux comprendre comment passer une fonction en paramètre.
Supposons que vous ayez la page Parent et que vous souhaitiez ouvrir une fenêtre contextuelle enfant. Dans la page parent, il y a une zone de texte qui doit être remplie en fonction de la zone de texte contextuelle enfant.
Ici, vous devez créer un délégué.
Parent.cs // déclaration des délégués délégué public void FillName (String FirstName);
Créez maintenant une fonction qui remplira votre zone de texte et la fonction devrait mapper les délégués
Maintenant, cliquez sur le bouton, vous devez ouvrir une fenêtre contextuelle enfant.
Dans le constructeur ChildPopUp, vous devez créer un paramètre de «type délégué» de la page parent //
ChildPopUp.cs
la source
Si vous souhaitez passer la méthode comme paramètre, utilisez:
la source
Voici un exemple sans paramètre: http://en.csharp-online.net/CSharp_FAQ:_How_call_a_method_using_a_name_string
avec params: http://www.daniweb.com/forums/thread98148.html#
vous passez essentiellement un tableau d'objets avec le nom de la méthode. vous utilisez ensuite les deux avec la méthode Invoke.
params Paramètres Object []
la source
La deuxième classe est Client, qui utilisera la classe de stockage. Il a une méthode Main qui crée une instance de PersonDB, et il appelle la méthode Process de cet objet avec une méthode définie dans la classe Client.
la source