Я - разработчик C++, использовавший сигналы и слоты в C++, чтобы мне, кажется, походит на делегатов в c#. Я нашел меня в недоумении в поиске функциональности предоставленным, "связывают" и чувствуют, что я должен пропускать что-то.
Я чувствую, что что-то как следующее, которое возможно в C++, должно быть возможным в c# с делегатами. Вот некоторый psudo-код для того, что я сделал бы в C++:
Slot<void> someCallback;
int foo(int i)
{
std::cout << "Value: " << i << "\n";
return i;
}
int main()
{
int i = 0;
Slot<int> someCallback = bind( fun_ptr(foo), i );
++i; // added to show that late evaluation would be a non-trivial difference
int result = someCallback();
assert( result == 0 );
return 0;
}
К сожалению, я не смог найти любую ссылку на привязку/повторное переплетение относительно делегатов c#. Я пропускаю что-то? Там некоторый радикально другой путь состоит в том, чтобы сделать это в c#?
В C # мы делаем что-то вроде этого:
class Program {
static Action Curry<T>(Action<T> action, T parameter) {
return () => action(parameter);
}
static void Foo(int i) {
Console.WriteLine("Value: {0}", i);
}
static void Main(string[] args) {
Action curried = Curry(Foo, 5);
curried();
}
}
четко метод FO
соответствует вашему методу foo
, просто с соответствующими вызовами Console.writeline
вместо STD :: Cout
.
Далее мы объявляем метод Curry
, который принимает действие
и возвращает действие
. В целом действие
является делегатом, который принимает один параметр типа T
и возвращает void
. В частности, FOO
- это действие
, поскольку он принимает один параметр типа int
и возвращает void
. Что касается возврата типа карри
, он объявлен как действие
. Действие
является делегатом, который не имеет никаких параметров и возврат void
.
Определение карри
довольно интересно. Мы определяем действие с использованием выражения лямбда, которое является очень особенной формой анонимного делегата. Фактически
() => action(parameter)
говорит, что параметр
параметр сопоставлен на действие
, оцениваемых в параметра
.
Наконец, в Главная
Мы объявляем экземпляр действий
с именем Curryed
, который является результатом применения Curry
на Foo
с параметром 5
. Это играет одинаковую роль, что и BING (Fun_PTR (FOO), 5)
в вашем примере C ++.
Наконец, мы призываем вновь сформированные делегат Curred
через синтаксис Curry ()
. Это похоже на SomeCallback ()
в вашем примере.
Необработанный термин для этого Carrying .
Как более интересный пример, рассмотрите следующее:
class Program {
static Func<TArg, TResult> Curry<TArg, TResult>(
Func<TArg, TArg, TResult> func,
TArg arg1
) {
return arg => func(arg1, arg);
}
static int Add(int x, int y) {
return x + y;
}
static void Main(string[] args) {
Func<int, int> addFive = Curry<int, int>(Add, 5);
Console.WriteLine(addFive(7));
}
}
Здесь мы объявляем метод Curry
, который принимает делегат ( FUNC
, который принимает Два параметра одного типа TARG
и возвращает значение какого-либо другого типа Tresult
и параметр типа TARG
и возвращает делегат, который принимает один параметр Тип TARG
и возвращает значение типа Tresult
( FUNC
).
Затем, как тест, который мы объявляем методом Добавьте
, которые принимают два параметра типа INT
и возвращает параметр типа int
(A функция
). Затем В Главная
Мы создали новый делегат имени AddFive
, который действует как метод, который добавляет пять к его входному параметру. Таким образом,
Console.WriteLine(addFive(7));
принты 12
на консоли.
Чтобы начать вас, вы должны хранить номер в каком-то массиве, как std :: вектор (цифра для каждой позиции в массиве), и вам нужно найти определенный алгоритм, который будет рассчитать факториал (возможно, в какой-то специализированный класс). ;)
-121--2410550-Попробуйте следующее
class Example {
static void foo(int i) {
Console.WriteLine(i);
}
public static void Main() {
Action someCallback = () => foo(5);
someCallback();
}
}
или для чего-то еще ближе к C ++ Counter Part
class Example {
static void foo(int i) {
Console.WriteLine(i);
}
static Action bind<T>(Action<T> action, T value) {
return () => action(value);
}
public static void Main() {
Action someCallback = bind(foo, 5);
someCallback();
}
}
Объяснение. Здесь происходит то, что я создаю новый делегат с помощью лямбда. Лямбда - это выражение, начиная с () =>
. В этом случае он создает делегат, принимающий никаких аргументов и не производим никакого значения. Он совместим с действием типа
.