Подпись массива конвейерных функций C # - PullRequest
0 голосов
/ 22 мая 2018

Имеет ли система типов c # возможность указать функцию, которая принимает перечисляемое число функций, которые коммутируют для формирования конвейера?

Эффект будет аналогичен цепочке, но вместо

var pipeline = a.Chain(b).Chain(c)

можно написать

var pipeline = CreatePipeline(a,b,c)

где a, b и c - функции?Я включил небольшой пример кода для иллюстрации, спасибо.

void Main()
{
    Func<int, string>       a = i => i.ToString();
    Func<string, DateTime>  b = s => new DateTime(2000,1,1).AddDays(s.Length);
    Func<DateTime, bool>    c = d => d.DayOfWeek == DayOfWeek.Wednesday;

    //var myPipeline = CreatePipeline(a, b, c);

    Func<int, bool> similarTo =  i => c(b(a(i))) ;

    Func<int, bool> isThisTheBestWeCanDo = a.Chain(b).Chain(c);

}

public static class Ext{

    //public static Func<X, Z> CreatePipeline<X,Z>(params MagicFunc<X..Y>[] fns) {
    //  return 
    //}

    public static Func<X, Z> Chain<X,Y,Z>(this Func<X,Y> a, Func<Y,Z> b)
    {
        return x => b(a(x));
    }
}

1 Ответ

0 голосов
/ 23 мая 2018

Вы можете рассмотреть это решение :

public class Pipeline
{
    public Func<object, object> CreatePipeline(params Func<object, object>[] funcs)
    {
        if (funcs.Count() == 1)
            return funcs[0];

        Func<object, object> temp = funcs[0];            
        foreach (var func in funcs.Skip(1))
        {
            var t = temp;
            var f = func;               
            temp = x => f(t(x));
        }                
        return temp;
    }
}

Использование:

Func<int, string> a = x => (x * 3).ToString();
Func<string, bool> b = x => int.Parse(x.ToString()) / 10 > 0;
Func<bool, bool> c = x => !x;

var pipeline = new Pipeline();
var func = pipeline.CreatePipeline(x => a((int)x), x => b((string)x), x => c((bool)x));

Console.WriteLine(func(3));//True
Console.WriteLine(func(4));//False
...