在C#中,你能把一个委托的结果链接成另一个的输入吗
本文关键字:结果 链接 输入 另一个 一个 | 更新日期: 2023-09-27 18:19:30
我正在寻找一种方法来链接多个委托,这样一个委托的结果就变成了下一个的输入。我正试图把它用在方程求解程序中,其中的部分是用不同的方法完成的。其想法是,当您构建方程时,程序会添加代理并按特定顺序将其链接,以便正确求解。如果有更好的方法来解决这个问题,请分享。
这可能会有所帮助:
public static Func<T1, TResult> Compose<T1, T2, TResult>(Func<T1, T2> innerFunc, Func<T2, TResult> outerFunc) {
return arg => outerFunc(innerFunc(arg));
}
这将执行函数组合,运行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);
是的,这是可能的-您需要确保委托的返回类型是被调用委托的参数类型。
许多LINQ都是以这种方式构建的,不过您可能需要了解表达式。
您所描述的API类型称为Fluent API。请参阅上一篇文章,以获得一个好的教程。
关于委托链接,请查看.NET 3.5中的LINQ扩展方法,特别是传递给函数的lambda函数(委托)是如何产生IEnumerable结果的,然后该结果可以与另一个扩展方法+lambda链接。
在您的特定情况下,您可能需要创建一个名为Functor的类来接受委托并返回另一个Functor,该Functor也可以由委托操作。
致问候,
使用GetInvocationlist可以实现这一点。
Delegate[] chain = chained.GetInvocationList();
int res = 10;
for( int i = 0; i < chain.Length; i++ )
{
//Call chain[i]
res = chain[i](res);
}
我自己也在处理一个类似的问题,涉及调用委托序列并将一个委托的输出传递给下一个(等等…),所以我想你可能有兴趣看看我开发的作为概念验证的代码:
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;
}
}
序列必须包含相同类型的委托,因此不如已经接受的答案强大,但经过一些调整,这两个代码位可以组合起来提供强大的解决方案。