есть ли какой-либо путь, как возвратить лямбду из другой лямбды рекурсивно?
Все, что я хочу сделать, является конечным автоматом, реализованным как лямбда, которая возвращает лямбду, реализовывая другое состояние (или пустой указатель).
вложенный Func <> не будет работать, как я хочу.
C#.NET 3.5
Пример:
машина, 3 состояния, псевдоязык
private Lambda State1()
{
if (SomeConditionIsMet)
return State2;
else
return State1;
}
private Lambda State2()
{
while (SomeConditionIsMet)
return State2;
else
return State3;
}
private Lambda State3()
{
LogEnd();
return NULL;
}
public void FSM()
{
Lambda _currentState = State1;
while(_currentState != NULL)
{
_currentState = _currentState();
}
}
Я знаю, что я могу обходное решение это использование enum+switch, например, но мне просто любопытно, если я могу сделать это.
Я считаю, что вы можете объявить тип делегата: публичный делегат Lambda Lambda ()
, который возвращает делегат своего собственного типа. Во всяком случае, он компилируется.
Вы можете иметь метод, который строит и возвращает дерево выражений:
public Expression GetExpression()
{
}
Также построение деревьев выражений в .NET 4.0 было значительно улучшено.
Конечно, вы можете вернуть лямбду из другой лямбды:
Func<int, Func<int, int>> makeAdder = x => y => x + y;
Func<int, int> addTen = makeAdder(10);
Console.WriteLine(addTen(20)); // 30
С каким аспектом синтаксиса у вас возникли проблемы? Мне интересно знать, как люди ошибаются в таких вещах, потому что это помогает нам в следующий раз лучше разработать язык и документацию.
UPDATE:
ну, но вы не можете вернуть лямбду, возвращая лямбду
Конечно, можете.
Func<int, Func<int, int>> GetAdderMaker()
{
return x => y => x + y;
}
Здесь мы возвращаем лямбду, которая возвращает лямбду. Почему вы считаете, что это невозможно?
UPDATE:
Ага, я понял. Вы считаете, что слово "лямбда" означает "делегат". Это не так. Лямбда - это выражение, которое можно преобразовать в делегат.
Если вам нужен делегат, который возвращает делегат, то просто объявите его. Это совершенно законно. Например, вот делегат под названием "комбинатор" - комбинатор - это делегат, который принимает себя и возвращает себя:
delegate D D(D d);
Это делегат с именем D, который принимает D и возвращает D.
Вы можете создать лямбда-выражение, совместимое с этим типом делегата. Например:
D I = x=>x;
- это комбинатор Identity. Или
D M = x=>x(x);
- комбинатор Mockingbird в причудливой характеристике комбинаторов Раймонда Смуллиана.
Как вы правильно заметили, не существует способа сделать общий Func, который был бы таким комбинатором. Я написал статью об этом факте еще в 2006 году:
http://blogs.msdn.com/ericlippert/archive/2006/06/23/standard-generic-delegate-types-part-two.aspx