Все динамично
"Нет никакого времени компиляции". Все в Python - время выполнения. Модуль 'определяется' путем выполнения источника модуля, от начала до конца, точно так же, как сценарий, и получающееся пространство имен является пространством атрибута модуля. Аналогично, класс 'определяется' путем выполнения тела класса, от начала до конца, и получающееся пространство имен является пространством атрибута класса. Тело класса может содержать абсолютно произвольный код - включая операторов импорта, циклы и другие операторы класса. При создании класса функционируйте или даже модуль 'динамично', относительно как иногда просят, не твердо; на самом деле невозможно избежать, так как все 'динамично'.
Вам просто нужно указать конкретные типы. Например:
Func<Func<int, int>, Func<int, int>>
представляет функцию, которая принимает (функция, преобразующая int во второй int) и возвращает (функция, преобразующая int во второй int). Или взять две функции и вернуть третью:
Func<Func<int, int>, Func<int, int>, Func<int, int>>
Например:
Func<Func<int, int>, Func<int, int>> applyTwice = (f => x => f(f(x));
Это может быть возвращено в общем случае методом:
public static Func<Func<T,T>, Func<T,T>> ApplyTwice<T>()
{
return func => x => func(func(x));
}
Если вы хотите суммировать две функции, вы можете сделать:
public static Func<int, int> Sum(Func<int, int> first, Func<int, int> second)
{
return x => first(x) + second(x);
}
Теперь, чтобы применить это :
Func<int, int> doubler = x => x * 2;
Func<int, int> squarer = x => x * x;
Func<int, int> doublePlusSquare = Sum(doubler, squarer);
Console.WriteLine(doublePlusSquare(5)); // Prints 35
(Непроверено, но все в порядке ...)
Если у вас нет доступных C # 3 и .NET 3.5, объявите следующих делегатов:
public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T arg);
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
(Подробнее см. В моем Страница версий C # .)
Затем вам нужно будет использовать анонимные методы, например
public static Func<int, int> Sum(Func<int, int> first, Func<int, int> second)
{
return delegate(int x) { return first(x) + second(x); };
}
Func<int, int> doubler = delegate (int x) { return x * 2; };
Func<int, int> squarer = delegate (int x) { return x * x; };
Func<int, int> doublePlusSquare = Sum(doubler, squarer);
Console.WriteLine(doublePlusSquare(5)); // Prints 35
Как сказал Джон:
Func<int, int> f = i => i * 2;
Func<int, int> g = i => i * i;
Func<int, int> sum = i => f(i) + g(i);
Однако, если вы хотите создать метод Sum для других типов, кроме Func
static Func<T, T> Sum<T>(Func<T, T> f, Func<T, T> g)
{
ParameterExpression p = Expression.Parameter(typeof(T), "i");
Expression<Func<T, T>> sumExpression =
Expression.Lambda<Func<T, T>>(
Expression.Add(
Expression.Invoke(Expression.Constant(f), p),
Expression.Invoke(Expression.Constant(g), p)),
p);
return sumExpression.Compile();
}
Это работает для любого типа T, который определяет оператор «+». Только будьте осторожны со снижением производительности, которое вы получите при компиляции лямбда-выражения.