我正在创建一个责任链管道,使用管道System.Func<T, T>
中的每个功能都对下一个功能的引用。
在构建管道时,由于无法重新分配管道功能,因此无法通过引用传递内部函数,因为它引发了StackOverflowException,例如:
Func<string, Func<string, string>, string> handler1 = (s, next) => {
s = s.ToUpper();
return next.Invoke(s);
};
Func<string, string> pipeline = s => s;
pipeline = s => handler1.Invoke(s, pipeline);
pipeline.Invoke("hello"); // StackOverFlowException
我可以解决这个问题:
Func<string, Func<string, string>, string> handler1 = (s, next) => {
s = s.ToUpper();
return next.Invoke(s);
};
Func<Func<string, string>, Func<string, string>> closure =
next => s => handler1.Invoke(s, next);
Func<string, string> pipeline = s => s;
pipeline = closure.Invoke(pipeline);
pipeline.Invoke("hello");
但是,我想知道是否有更有效的方法来构建此功能链,也许使用表达式?
那个怎么样?这样,您可以构建任意长度的链。
void Main()
{
Func<string, string> f1 = x => x.Replace("*", string.Empty);
Func<string, string> f2 = x => x.Replace("--", string.Empty);
Func<string, string> f3 = x => x.ToUpper();
//Func<string, string> pipeline = x => f3(f2(f1(x)));
Func<string, string> pipeline = Pipeline(f1, f2, f3);
pipeline.Invoke("te-*-st").Dump(); // prints "TEST"
}
Func<T, T> Pipeline<T>(params Func<T, T>[] functions)
{
Func<T, T> resultFn = x => x;
for (int i = 0; i < functions.Length; i++)
{
Func<T, T> f = functions[i];
Func<T, T> fPrev = resultFn;
resultFn = x => f(fPrev(x));
}
return resultFn;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句