Puis-je utiliser une liste < T > comme une collection de pointeurs de méthode? (C #)
Question
Je souhaite créer une liste de méthodes à exécuter. Chaque méthode a la même signature. J'ai pensé mettre des délégués dans une collection générique, mais je continue à avoir cette erreur:
"méthode" est une "variable" mais est utilisé comme une "méthode"
En théorie, voici ce que je voudrais faire:
List<object> methodsToExecute;
int Add(int x, int y)
{ return x+y; }
int Subtract(int x, int y)
{ return x-y; }
delegate int BinaryOp(int x, int y);
methodsToExecute.add(new BinaryOp(add));
methodsToExecute.add(new BinaryOp(subtract));
foreach(object method in methodsToExecute)
{
method(1,2);
}
Des idées sur la façon de procéder? Merci!
La solution
Vous devez convertir l'objet de la liste
de la liste en BinaryOp
ou, mieux, utilisez un paramètre de type plus spécifique pour la liste:
delegate int BinaryOp(int x, int y);
List<BinaryOp> methodsToExecute = new List<BinaryOp>();
methodsToExecute.add(Add);
methodsToExecute.add(Subtract);
foreach(BinaryOp method in methodsToExecute)
{
method(1,2);
}
Autres conseils
Avec .NET 3.0 (ou 3.5?), vous avez des délégués génériques.
Essayez ceci:
List<Func<int, int, int>> methodsToExecute = new List<Func<int, int, int>>();
methodsToExecute.Add(Subtract);
methodsToExecute.Add[0](1,2); // equivalent to Subtract(1,2)
List<Func<int, int, int>> n = new List<Func<int, int, int>>();
n.Add((x, y) => x + y);
n.Add((x, y) => x - y);
n.ForEach(f => f.Invoke(1, 2));
J'aime mieux l'implémentation de Khoth mais je pense que votre erreur de compilateur est due au fait que vous n'avez pas transtypé la méthode sur un BinaryOp avant d'essayer de l'invoquer. Dans votre boucle foreach, il ne s'agit que d'un "objet". Changez votre style pour qu'il ressemble à celui de Khoth et je pense que cela fonctionnerait.
Chaque fois que j'ai été tenté de faire quelque chose comme cela, j'ai constaté qu'il est généralement préférable de refactoriser votre conception pour utiliser le modèle de commande, d'autant plus que toutes vos méthodes ont les mêmes paramètres. De cette façon, vous disposez de beaucoup plus de flexibilité.
Je n'ai pas essayé, mais en utilisant une liste < Action < t > > le type devrait pouvoir le faire.
Demandez-leur d'implémenter l'interface commune, par exemple IExecuteable, puis créez une liste < IExecutable >
En outre, à l'aide de délégués:
class Example
{
public delegate int AddDelegate(int x, int y);
public List<AddDelegate> methods = new List<AddDelegate>();
int Execute()
{
int sum = 0;
foreach(AddDelegate method in methods)
{
sum+=method.Invoke(1, 2);
}
return sum;
}
}