How to get input and return type of delegate stored in list<dynamic> in c#?

I want to create list of method. and run this list of method in order. The input of next method is output of current method.

So, this is my code for these, and i need to get input, output type.

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 ?
}
Jon Skeet
people
quotationmark

Yes, you can use foreach, and call Invoke dynamically - you'll need the input to be dynamic as well though:

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}");
    }
}

(It's odd that your first function ignores the input, by the way.)

Note that there's no compile-time type safety here - if one of your functions actually required a string, you'd only find out at execution time. Without knowing how you're creating the delegates in your real code, it's hard to know exactly the best way to fix this, but here's one option:

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}");
    }
}

people

See more on this question at Stackoverflow