Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#中,能否将一个委托的结果链接为另一个委托的输入?_C#_Delegates_Chaining - Fatal编程技术网

在C#中,能否将一个委托的结果链接为另一个委托的输入?

在C#中,能否将一个委托的结果链接为另一个委托的输入?,c#,delegates,chaining,C#,Delegates,Chaining,我正在寻找一种方法来链接多个代理,以便其中一个代理的结果成为下一个代理的输入。我试着在方程求解程序中使用它,其中的部分是通过不同的方法完成的。其思想是,当您构建方程式时,程序会添加代理并按特定顺序将其链接,以便可以正确求解。如果有更好的方法解决问题,请分享。是的,这是可能的-您需要确保委托的返回类型是被调用委托的参数类型 很多LINQ都是以这种方式构建的,不过您可能想看看。您描述的API类型称为。请看前面的文章以获得一个好的教程 关于委托链接,请看一下.NET 3.5中的LINQ扩展方法,特别是

我正在寻找一种方法来链接多个代理,以便其中一个代理的结果成为下一个代理的输入。我试着在方程求解程序中使用它,其中的部分是通过不同的方法完成的。其思想是,当您构建方程式时,程序会添加代理并按特定顺序将其链接,以便可以正确求解。如果有更好的方法解决问题,请分享。

是的,这是可能的-您需要确保委托的返回类型是被调用委托的参数类型


很多LINQ都是以这种方式构建的,不过您可能想看看。

您描述的API类型称为。请看前面的文章以获得一个好的教程

关于委托链接,请看一下.NET 3.5中的LINQ扩展方法,特别是lambda函数(委托)是如何传递给函数结果的,结果是IEnumerable结果,然后可以与另一个扩展方法+lambda链接

在您的特定情况下,您可能需要创建一个名为Functor的类来接受委托并返回另一个同样可以由委托操作的Functor

致以最诚挚的问候,

这可能有助于:

public static Func<T1, TResult> Compose<T1, T2, TResult>(Func<T1, T2> innerFunc, Func<T2, TResult> outerFunc) {
    return arg => outerFunc(innerFunc(arg));
}

使用GetInvocationlist可以实现这一点

 Delegate[] chain = chained.GetInvocationList();

        int res = 10;
        for( int i = 0; i < chain.Length; i++ ) 
          {
              //Call chain[i]
                res =  chain[i](res);
          }
Delegate[]chain=chained.GetInvocationList();
int res=10;
对于(int i=0;i
我自己也在处理一个类似的问题,涉及调用一系列委托并将一个委托的输出传递给下一个委托(等等…),所以我想您可能有兴趣看到我开发的代码作为概念证明:

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;
    }
}
静态类程序
{
私有静态IList委派列表=
新名单()
{
AddOne,AddOne,AddOne,AddOne,AddOne,
AddOne,AddOne,AddOne,AddOne,AddOne,
};
静态void Main(字符串[]参数)
{
整数=12;
WriteLine(“起始编号:{0}”,编号);
Console.WriteLine(“结束编号:{0}”),
delegateList.InvokeChainDelegates(编号));
Console.ReadLine();
}
公共静态int AddOne(int num){return num+1;}
public static T InvokeChainDelegates(此IEnumerable源,
T起始值)
{
T结果=起始值;
foreach(源代码中的Func函数)
{
结果=功能(结果);
}
返回结果;
}
}

序列必须包含相同类型的委托,因此不如已经接受的答案强大,但只要稍加调整,两位代码就可以组合起来提供强大的解决方案。

也许表达式树值得研究()?我认为所有人都应该需要相同的输入类型并返回特定的类型。@Snowppy-如果你希望每个人都可以链接到其他人,是的。这是我们的基础。
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;
    }
}