Как создать полностью параметризованный делегат метода в C #? - PullRequest
4 голосов
/ 05 октября 2010

В c # мы можем создавать делегатов различными способами (например, Action <>, Func <>, делегат, лямбда-выражения и т. Д.). Но когда вы вызываете эти методы, вы должны предоставить значения параметров для вызываемого вами делегата:

delegate int del(int i);   
del myDelegate = x => x * x;
int j = myDelegate(5);

Есть ли способ в c # инкапсулировать метод делегировать значения параметра WITH? По сути, задержать вызов полностью параметризованного метода? То есть вам не нужно указывать значения параметров во время вызова?

Например, что-то вроде этого неверного кода:

delegate int del(int i);   
del myDelegate(5) = x => x * x;
int j = myDelegate;

Я знаю, что вариант использования не сразу очевиден. В случае, который я сейчас рассматриваю, у меня есть недетерминированный метод, который я хотел бы, чтобы вызывающая сторона могла вызывать без необходимости содержать или знать параметры, необходимые для метода. Одним из способов достижения этого было бы создание класса, который инкапсулирует как значения параметров, так и делегат метода, и на который ссылается и вызывает вызывающая сторона. Но мне просто любопытно, есть ли альтернативный, более лаконичный способ.

Ответы [ 4 ]

12 голосов
/ 05 октября 2010

Это называется карри .

Например:

Action curried = () => myFunc(5);

Или

Func<int, int, int> multiplier = (x, y) => x * y;
Func<int, int> doubler = x => multiplier(x, 2);
int eight = doubler(4);
1 голос
/ 05 октября 2010
Func<int, int> myDelegate = x => x * x;
Func<int> myDelegate5 = () => myDelegate(5);
int j = myDelegate5();
1 голос
/ 05 октября 2010

Вы всегда можете заключить одного делегата в другого. Как уже упоминалось SLaks, это называется curry :

Func<int, int> square = i => i * i;
Func<int> squareFive = () => square(5);

int j = squareFive();
0 голосов
/ 18 декабря 2010

Это может быть сделано довольно удобно без лямбд, с помощью некоторых общих классов и вспомогательных функций.Я использовал такой подход в некотором коде vb.net/vs2005.Если цель состоит в том, чтобы получить MethodInvoker, который вызывает функцию с тремя аргументами типов T, U и V, то создайте класс ParamInvokerкоторый содержит поля param1, param2 и param3 (как типы T, U и V) и Action (типа Action) и имеет метод DoIt (void), который вызывает действие (param1, param2, param3).Универсальные классы и вспомогательные функции становятся повторяющимися, но синтаксис довольно приятный.Например (синтаксис vb, из памяти и синтаксис C #, предположения):

  TheMethodInvoker = MakeParamInvoker(AddressOf MyFunction, 5, "Hello")
or
  TheMethodInvoker = MakeParamInvoker(MyFunction, 5, "Hello")

при условии, что MyFunction принимает целое число и строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...