我正在寻找一种链接多个委托的方法,因此一个委托的结果成为下一个委托的输入。我试图在方程求解程序中使用它,其中部分通过不同的方法完成。这个想法是,当你构建方程式时,程序会添加代理并按特定顺序链接它们,因此可以正确解决。如果有更好的方法来解决问题,请分享。
答案 0 :(得分:7)
这可能会有所帮助:
public static Func<T1, TResult> Compose<T1, T2, TResult>(Func<T1, T2> innerFunc, Func<T2, TResult> outerFunc) {
return arg => outerFunc(innerFunc(arg));
}
执行function composition,运行innerFunc
并在提供初始参数时将结果传递给outerFunc
:
Func<double, double> floor = Math.Floor;
Func<double, int> convertToInt = Convert.ToInt32;
Func<double, int> floorAndConvertToInt = Compose(floor, convertToInt);
int result = floorAndConvertToInt(5.62);
Func<double, int> floorThenConvertThenAddTen = Compose(floorAndConvertToInt, i => i + 10);
int result2 = floorThenConvertThenAddTen(64.142);
答案 1 :(得分:3)
是的,这是可能的 - 您需要确保委托的返回类型是被调用的委托的参数类型。
很多LINQ都是以这种方式构建的,不过你可能想看看expressions。
答案 2 :(得分:0)
您描述的API类型称为Fluent API。查看前面的文章以获得一个好的教程。
关于委托链接,请看一下.NET 3.5中的LINQ扩展方法,特别是lambda函数(委托)如何传递给IEnumerable结果中的函数结果,然后可以用另一个扩展方法+ lambda链接
在您的特定情况下,您可能需要创建一个名为Functor的类来接受委托并返回另一个也可由委托操作的Functor。
致以最诚挚的问候,
答案 3 :(得分:0)
使用GetInvocationlist可以实现此目的。
Delegate[] chain = chained.GetInvocationList();
int res = 10;
for( int i = 0; i < chain.Length; i++ )
{
//Call chain[i]
res = chain[i](res);
}
答案 4 :(得分:0)
我自己一直在研究一个类似的问题,包括调用委托的序列并将一个委托的输出传递给下一个委托(依此类推......)以为你可能会感兴趣看到我开发的代码作为概念验证:
static class Program
{
private static IList<Func<int, int>> delegateList =
new List<Func<int, int>>()
{
AddOne, AddOne, AddOne, AddOne, AddOne,
AddOne, AddOne, AddOne, AddOne, AddOne,
};
static void Main(string[] args)
{
int number = 12;
Console.WriteLine("Starting number: {0}", number);
Console.WriteLine("Ending number: {0}",
delegateList.InvokeChainDelegates(number));
Console.ReadLine();
}
public static int AddOne(int num) { return num + 1; }
public static T InvokeChainDelegates<T>(this IEnumerable<Func<T, T>> source,
T startValue)
{
T result = startValue;
foreach (Func<T, T> function in source)
{
result = function(result);
}
return result;
}
}
序列必须包含相同类型的委托,因此不像已经接受的答案那样强大,但是通过一些调整,两个代码位可以组合起来提供强大的解决方案。