Sq1
и Sq2
являются идентичными функциями, а не лямбдами.Sq2
использует синтаксис тела выражения *1007*, что позволяет упростить простые методы.Sq2
по сути:
public int Sq2(int i) {
return i * i;
}
Вы можете использовать Sharplab.io , чтобы увидеть сгенерированный код в обоих случаях.Вы увидите, что тело обоих методов одинаково
Вы не можете заставить функцию Sq3
вести себя так же, как Sq4
, потому что Sq4
с другой стороны имеет тип Func поле , которое содержит делегат x => x * x
.Sq3
с другой стороны, это функция, которая возвращает Func
, распространенную идиому в функциональном программировании.
Вы можете использовать Sq4
, как если бы это была функция, например:
var result=Sq4(2);
Что касается Sq3, то, что вы делаете, зависит от того, что вы хотите сделать.Если вы хотите только выполнить функцию, используйте тот же синтаксис, что и Sq1
или Sq2
.Если вы действительно хотите вернуть Func<>
, вы можете использовать что-то вроде этого:
public Func<int,int> Sq3F()
{
return (int i)=>i*i;
}
И использовать это так:
var fun=Sq3F();
var result=fun(4);
Почему Func <>?
Это выглядит не так много, пока вы не поймете, что можете передавать функции в качестве параметров и динамически создавать сложные преобразования, например:
public Func<int,double> LogF(Func<int,int> fun)
{
return (int i)=>Math.Log(fun(i));
}
...
var func=LogF(Sq3F());
var result=func(4);
Еще один распространенный тип частичное применение - взять функцию с несколькими аргументами и создать другую, в которой некоторые аргументы являются фиксированными.Допустим, вы хотите создать метод Log с одним аргументом, который работает для специфической базы, что означает, что вы не можете просто использовать `Math.Log (double, double).Вы можете сделать это:
public Func<double,double> LogN(double N)
{
return (double d)=>Math.Log(d,N);
}
...
var log5F=LogN(5);
var result=log5F(5);