Могу ли я использовать List<T> как коллекцию указателей методов?(С#)
Вопрос
Я хочу создать список методов для выполнения.Каждый метод имеет одну и ту же подпись.Я думал о том, чтобы поместить делегатов в общую коллекцию, но постоянно получаю эту ошибку:
«метод» — это «переменная», но используется как «метод».
Теоретически вот что я хотел бы сделать:
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);
}
Есть идеи, как это сделать?Спасибо!
Решение
Вам нужно бросить object
в списке к BinaryOp
, или, лучше, используйте для списка более конкретный параметр типа:
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);
}
Другие советы
Используя .NET 3.0 (или 3.5?), у вас есть общие делегаты.
Попробуй это:
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));
Мне больше нравится реализация Хота, но я думаю, что причина вашей ошибки компилятора заключается в том, что вы не приводите метод к BinaryOp, прежде чем попытаться его вызвать.В вашем цикле foreach это просто «объект».Измените свой foreach, чтобы он выглядел как у Хота, и я думаю, это сработает.
Всякий раз, когда у меня возникало искушение сделать что-то подобное, я обнаруживал, что обычно лучше провести рефакторинг вашего проекта, чтобы использовать шаблон команды, тем более, что все ваши методы имеют одинаковые параметры.Этот способ обеспечивает гораздо большую гибкость.
Я не пробовал, но использование типа List< Action< t>> должно быть в состоянии это сделать.
Пусть они все реализуют общий интерфейс, скажем, IExecuteable, а затем создайте List<IExecutable>.
Кроме того, используя делегатов:
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;
}
}