Puis-je utiliser une liste < T > comme une collection de pointeurs de méthode? (C #)

StackOverflow https://stackoverflow.com/questions/135451

  •  02-07-2019
  •  | 
  •  

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!

Était-ce utile?

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;
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top