如何获取列表中存储的委托的输入和返回类型<;动态>;在c#中?

如何获取列表中存储的委托的输入和返回类型<;动态>;在c#中?,c#,methods,dynamic,reflection,C#,Methods,Dynamic,Reflection,我想创建方法列表。并按顺序运行此方法列表。 下一个方法的输入是当前方法的输出 这是我的代码,我需要得到输入,输出类型 static void Main( string [ ] args ) { List<dynamic> temp = new List<dynamic>(); Func<int,int> fn1 = new Func<int,int>( x => 3); Func<int,int> fn

我想创建方法列表。并按顺序运行此方法列表。 下一个方法的输入是当前方法的输出

这是我的代码,我需要得到输入,输出类型

static void Main( string [ ] args )
{
    List<dynamic> temp = new List<dynamic>();

    Func<int,int> fn1 = new Func<int,int>( x => 3); 
    Func<int,int> fn2 = new Func<int,int>(x  => x + 3);
    Func<int,int> fn3 = new Func<int,int>(x  => x + 30);
    Func<int,double> fn4 = new Func<int,double>(x  => x*0.2);

    temp.Add( fn1 ); 
    temp.Add( fn2 );
    temp.Add( fn3 );
    temp.Add( fn4 );

    int input = 6;
    // use for or foreach or something 
    // output ?
}
static void Main(字符串[]args)
{
列表温度=新列表();
Func fn1=新Func(x=>3);
Func fn2=新Func(x=>x+3);
Func fn3=新Func(x=>x+30);
Func fn4=新Func(x=>x*0.2);
温度添加(fn1);
温度添加(fn2);
温度添加(fn3);
温度添加(fn4);
int输入=6;
//用于或用于任何东西
//输出?
}

是的,您可以使用
foreach
,并动态调用
Invoke
——您还需要动态输入:

using System;
using System.Collections.Generic;

class Test
{
    static void Main()
    {
        Func<int,int> fn1 = new Func<int,int>(x => 3); 
        Func<int,int> fn2 = new Func<int,int>(x => x + 3);
        Func<int,int> fn3 = new Func<int,int>(x => x + 30);
        Func<int,double> fn4 = new Func<int,double>(x => x * 0.2);

        List<dynamic> pipeline = new List<dynamic> { fn1, fn2, fn3, fn4 };

        dynamic current = 6;
        foreach (dynamic stage in pipeline)
        {
            // current = stage(current) would work too, but I think it's less clear
            current = stage.Invoke(current);
        }
        Console.WriteLine($"Result: {current}");
    }
}
使用系统;
使用System.Collections.Generic;
课堂测试
{
静态void Main()
{
Func fn1=新Func(x=>3);
Func fn2=新Func(x=>x+3);
Func fn3=新Func(x=>x+30);
Func fn4=新Func(x=>x*0.2);
列表管道=新列表{fn1,fn2,fn3,fn4};
动态电流=6;
foreach(管道中的动态阶段)
{
//current=阶段(current)也会起作用,但我认为不太清楚
当前=阶段调用(当前);
}
WriteLine($“结果:{current}”);
}
}
(顺便说一下,第一个函数忽略了输入,这很奇怪。)

请注意,这里没有编译时类型安全性-如果您的函数之一实际需要字符串,您只能在执行时找到。在不知道如何在实际代码中创建委托的情况下,很难确切知道解决此问题的最佳方法,但这里有一个选项:

class Pipeline<TInput, TOutput>
{
    private readonly Func<TInput, TOutput> function;

    public Pipeline(Func<TInput, TOutput> function)
    {
        this.function = function;
    }

    public Pipeline<TInput, TNext> Then<TNext>(Func<TOutput, TNext> nextFunction) =>
        new Pipeline<TInput, TNext>(input => nextFunction(function(input)));

    public TOutput Process(TInput input) => function(input);
}

class Test
{
    static void Main()
    {
        Pipeline<int, double> pipeline = new Pipeline<int, int>(x => 3)
            .Then(x => x + 3)
            .Then(x => x + 30)
            .Then(x => x * 0.2);

        var result = pipeline.Process(6);
        Console.WriteLine($"Result: {result}");
    }
}
类管道
{
私有只读函数;
公共管道(Func函数)
{
这个函数=函数;
}
公共管道(Func nextFunction)=>
新管道(输入=>nextFunction(函数(输入));
公共TOutput进程(TInput输入)=>函数(输入);
}
课堂测试
{
静态void Main()
{
管道=新管道(x=>3)
.然后(x=>x+3)
.然后(x=>x+30)
。然后(x=>x*0.2);
var结果=管道过程(6);
WriteLine($“Result:{Result}”);
}
}

是的,您可以使用
foreach
,并动态调用
Invoke
——您还需要动态输入:

using System;
using System.Collections.Generic;

class Test
{
    static void Main()
    {
        Func<int,int> fn1 = new Func<int,int>(x => 3); 
        Func<int,int> fn2 = new Func<int,int>(x => x + 3);
        Func<int,int> fn3 = new Func<int,int>(x => x + 30);
        Func<int,double> fn4 = new Func<int,double>(x => x * 0.2);

        List<dynamic> pipeline = new List<dynamic> { fn1, fn2, fn3, fn4 };

        dynamic current = 6;
        foreach (dynamic stage in pipeline)
        {
            // current = stage(current) would work too, but I think it's less clear
            current = stage.Invoke(current);
        }
        Console.WriteLine($"Result: {current}");
    }
}
使用系统;
使用System.Collections.Generic;
课堂测试
{
静态void Main()
{
Func fn1=新Func(x=>3);
Func fn2=新Func(x=>x+3);
Func fn3=新Func(x=>x+30);
Func fn4=新Func(x=>x*0.2);
列表管道=新列表{fn1,fn2,fn3,fn4};
动态电流=6;
foreach(管道中的动态阶段)
{
//current=阶段(current)也会起作用,但我认为不太清楚
当前=阶段调用(当前);
}
WriteLine($“结果:{current}”);
}
}
(顺便说一下,第一个函数忽略了输入,这很奇怪。)

请注意,这里没有编译时类型安全性-如果您的函数之一实际需要字符串,您只能在执行时找到。在不知道如何在实际代码中创建委托的情况下,很难确切知道解决此问题的最佳方法,但这里有一个选项:

class Pipeline<TInput, TOutput>
{
    private readonly Func<TInput, TOutput> function;

    public Pipeline(Func<TInput, TOutput> function)
    {
        this.function = function;
    }

    public Pipeline<TInput, TNext> Then<TNext>(Func<TOutput, TNext> nextFunction) =>
        new Pipeline<TInput, TNext>(input => nextFunction(function(input)));

    public TOutput Process(TInput input) => function(input);
}

class Test
{
    static void Main()
    {
        Pipeline<int, double> pipeline = new Pipeline<int, int>(x => 3)
            .Then(x => x + 3)
            .Then(x => x + 30)
            .Then(x => x * 0.2);

        var result = pipeline.Process(6);
        Console.WriteLine($"Result: {result}");
    }
}
类管道
{
私有只读函数;
公共管道(Func函数)
{
这个函数=函数;
}
公共管道(Func nextFunction)=>
新管道(输入=>nextFunction(函数(输入));
公共TOutput进程(TInput输入)=>函数(输入);
}
课堂测试
{
静态void Main()
{
管道=新管道(x=>3)
.然后(x=>x+3)
.然后(x=>x+30)
。然后(x=>x*0.2);
var结果=管道过程(6);
WriteLine($“Result:{Result}”);
}
}

是否需要
.Invoke()
?简单的
阶段(当前)
有什么区别?这似乎也很好地编译和工作。@RenéVogt:我认为它更清晰,仅此而已。将进行编辑以澄清这一点。是否需要
.Invoke()
?简单的
阶段(当前)
有什么区别?这似乎也很好地编译和工作。@RenéVogt:我认为它更清晰,仅此而已。将编辑以澄清这一点。