Спрашивать об этом довольно сложно, и хотя решение кажется простым, непонятный уклон делегатов внутри делегатов, возвращенных еще большим числом делегатов, заставил мой мозг взорваться сам по себе.
Без дальнейших действий, Я объясню:
Сценарий состоит в том, что у вас есть делегаты перевода (Func [A, B]) и поведения перевода (Func [A, Func [Func [A, B], B]]).
Идея состоит в том, что вокруг данного перевода у вас будет определенный набор поведений, которые обертывают вызов к переводу, то есть - что они принимают A, не стесняйтесь делать с ним то, что они хотят,передать это следующему поведению, в то же время имея возможность изменить возвращаемое значение (B).
Вероятно, есть некоторая монада, чтобы описать это идеально, но, возможно, некоторый код поможет больше, чем что-либо.
Жертвы:
public class B
{
}
public class A
{
}
Делегат поведения
public delegate Func<Func<A, B>, B> TranslationBehavior(A input);
Функция, которая объединяет их в цепочку и возвращает Func, который позволяет перевестиИонная функция, которую нужно передать и получить новую функцию перевода, которая обернута поведением
static Func<Func<A, B>, Func<A, B>> Chain(IEnumerable<TranslationBehavior> behaviors)
{
throw new NotImplementedException();
}
сценарий использования
static void Main(string[] args)
{
var behaviors = new[]
{
(TranslationBehavior) (inp => next => next(inp)),
(TranslationBehavior) (inp => next => next(inp)),
(TranslationBehavior) (inp => next => next(inp)),
};
var input = new A();
var chained = Chain(behaviors);
var output = chained(a => new B());
}
В примере кода реализации поведения ничего не делаютput вызывает следующее поведение, и наша реализация перевода просто возвращает новый B.
Функция 'цепочка' является проблемной функцией, возможность связать поведение вместе ускользнула от меня, но чтобы доказать себе, что это должнона самом деле, я жестко запрограммировал наивное решение, которое специально объединяет три вида поведения:
static Func<Func<A, B>, Func<A, B>> Chain(IEnumerable<TranslationBehavior> behaviors)
{
var behavior1 = (TranslationBehavior)null;
var behavior2 = (TranslationBehavior)null;
var behavior3 = (TranslationBehavior)null;
return translation => input =>
behavior1(input)(transformed1 =>
behavior2(transformed1)(transformed2 =>
behavior3(transformed2)(translation)
)
);
}
Это работает, но очевидно;совершенно бесполезно.
Любая помощь по этому вопросу была бы действительно полезной, и любая информация о том, является ли это известным шаблоном или монадой, была бы действительно интересной, я не думаю, что этот кодовый код далек от обобщения.
Заранее спасибо, Стивен.