获得类型推理的聪明方法

本文关键字:方法 推理 类型 | 更新日期: 2024-10-24 04:53:42

有没有一种聪明的方法可以让类型推理在"Start"函数中工作,而无需在Pipe类上定义泛型类型?

使用start看起来像这样:

Pipe.Start<ToUpper, string, string>(...

我希望它是

Pipe.Start(...

用例的完整代码如下所示:

using System;
using System.Threading.Tasks;
namespace Code
{
    public class Pipe
    {
    private Func<object, Task> next;
    public static Section<TOut> Start<TStep, TIn, TOut>(Func<TStep> func, Func<TStep, TIn, TOut> runFunc)
    {
        var pipeline = new Pipe();
        var nextPipe = new Section<TIn>(pipeline);
        pipeline.next = o => nextPipe.Run((TIn)o);
        return nextPipe.Then(func, runFunc);
    }
    public async Task Run<TIn>(TIn start)
    {
        await next(start);
    }
    public class Section<TIn>
    {
        public Pipe Pipe { get; }
        private Func<TIn, Task> next;
        internal Section(Pipe pipe)
        {
            Pipe = pipe;
        }
        public async Task Run(Task<TIn> start)
        {
            if (next != null) await next(await start);
        }
        public async Task Run(TIn start)
        {
            if (next != null) await next(start);
        }
        public Section<TOut> Then<TStep, TOut>(Func<TStep> func, Func<TStep, TIn, TOut> filter)
        {
            var pipeLineStep = new Section<TOut>(Pipe);
            next = @in => pipeLineStep.Run(Task.FromResult(filter(func(), @in)));
            return pipeLineStep;
        }
        public Section<TOut> Then<TStep, TOut>(Func<TStep> func, Func<TStep, TIn, Task<TOut>> runFunc)
        {
            var pipeLineStep = new Section<TOut>(Pipe);
            next = @in => pipeLineStep.Run(runFunc(func(), @in));
            return pipeLineStep;
        }
    }
}
}

测试

using System.Linq;
using System.Threading.Tasks;
using FluentAssertions;
using Code;
using Xunit;
namespace Test
{
public class PipeTets
{
    [Fact]
    public async void FactMethodName()
    {
        var toUpper = new ToUpper();
        var toReverse = new ToReverse();
        var toLower = new ToLower();
        var toLength = new ToLength();
        var toDouble = new ToDouble();
        await Pipe.Start<ToUpper, string, string>(() => toUpper, (upper, s) => upper.Run(s))
                  .Then(() => toReverse, (reverse, s) => reverse.Run(s))
                  .Then(() => toLower, (lower, s) => lower.Run(s))
                  .Then(() => toLength, (length, s) => length.Run(s))
                  .Then(() => toDouble, (@double, i) => @double.Run(i))
                  .Pipe
                  .Run("lower");

        toUpper.Upper.Should().Be("LOWER");
        toReverse.Reverse.Should().Be("REWOL");
        toLower.Lower.Should().Be("rewol");
        toLength.Length.Should().Be(5);
        toDouble.Double.Should().Be(10);
    }
}
public class ToReverse
{
    public string Reverse;
    public string Run(string text)
    {
        Reverse = new string(text.Reverse().ToArray());
        return Reverse;
    }
}
public class ToUpper
{
    public string Upper;
    public string Run(string text)
    {
        Upper = text.ToUpper();
        return Upper;
    }
}
public class ToLower
{
    public string Lower;
    public Task<string> Run(string text)
    {
        Lower = text.ToLower();
        return Task.FromResult(Lower);
    }
}
public class ToLength
{
    public int Length;
    public Task<int> Run(string text)
    {
        Length = text.Length;
        return Task.FromResult(Length);
    }
}
public class ToDouble
{
    public int Double;
    public Task<int> Run(int text)
    {
        Double = text * 2;
        return Task.FromResult(Double);
    }
}
}

获得类型推理的聪明方法

只需明确定义参数类型:

await Pipe.Start(() => toUpper, (ToUpper upper, string s) => upper.Run(s))