【问题标题】:Method chaining in C#C#中的方法链
【发布时间】:2018-09-03 17:57:01
【问题描述】:

假设我有一些这样的代码

var addResult = GetAddResult(num1, num2);

var transformedResult = TransformResult(addResult );

if(CheckValidity(transformedResult))
{
    SendResult(transformedResult); 
}
else
{
    LogError(transformedResult);
}

我在很多地方都在写这样的代码。基本上它是一个函数调用,其中一个的返回值是另一个的输入。还有流量变化取决于一些条件检查。

有没有办法以更易读的方式编写?

例如

ExecuteFlow.GetAddResult(num1,num2).TransformResult.CheckValidity.IfTrue.SendResult.IfFalse.LogError;

为此道歉更多的是概念上的澄清。但我想知道这样的技术是否可行。

【问题讨论】:

标签: c#


【解决方案1】:

我认为你可以做到这一点

//let's assume this is the type that GetAddResult method is returning.
public class MyAddResult { ... }

//let's say this is what method TransformResult is returning.
public class MyTransformResult { ... }

public static class MyFlow {
    public static MyTransformResult TransformResult(this MyAddResult src) {
        ....
    }

    public static void IfValid(this MyTransformResult src, Action<MyTransformResult> methodIfTrue, Action<MyTransformResult> methodIfFalse) {
        if( CheckValidity(src) )
          methodIfTrue(src);

        methodIfFalse(src);
    }
}

//In another place
public void SendResult(MyTransformResult m) { ... }

//In another place
public void LogError(MyTransformResult m) { ... }

用法如下:

GetAddResult(num1, num2).TransformResult().IfValid(SendResult, LogError);

【讨论】:

    【解决方案2】:

    你可以写一个 C# 扩展,

    例如

    GetAddResult(num1, num2).Handle();
    

    扩展的位置:

    public static void Handle(this AddResult addResult)
    {
        var transformedResult = TransformResult(addResult);
    
        if(CheckValidity(transformedResult))
        {
            SendResult(transformedResult); 
        }
        else
        {
            LogError(transformedResult);
        }
    }
    

    或者更详细一点:

    GetAddResult(num1, num2).ToTransformResult().HandleValidity();
    

    使用这些扩展:

    public static TransformResult ToTransformResult(this AddResult addResult)
    {
        return TransformResult(addResult);
    }
    
    public static void HandleValidity(this TransformResult addResult)
    {
        if(CheckValidity(transformedResult))
        {
            SendResult(transformedResult); 
        }
        else
        {
            LogError(transformedResult);
        }
    }
    

    不确定这是否能满足您的所有要求。

    【讨论】:

    • 我同意我们可以通过扩展函数来提高可读性。然而,我的问题更多是关于有一些技术来用条件链接方法
    • 然后传递Action
    【解决方案3】:
    Result.OfAdding(1, 2)
        .Transform()
        .IfValid(thenInvokeThis: () => Debug.Print("Valid"),
            elseInvokeThis: () => Debug.Print("Invalid"));
    

    对 Dabbas 的解决方案稍作改动 - IsValid 工作得非常好,但我觉得初始设置可能会更顺畅。

    首先声明一个通用接口和一个静态工厂。

    interface IAddResult
    {
        int AddendA { get; set; }
        int AddendB { get; set; }
        int Sum { get; }
    }
    
    static class Result
    {
        public static IAddResult OfAdding(int a, int b)
        {
            // TODO: Return add result.
            throw new NotImplementedException();
        }
    }
    

    然后通过扩展添加链接功能。

    static class AddResultExtensions
    {
        public static IAddResult Transform(this IAddResult addResult)
        {
            // TODO: Transform add result.
            throw new NotImplementedException();
        }
    
        public static void IfValid(this IAddResult addResult, Action thenInvokeThis, 
            Action elseInvokeThis)
        {
            // TODO: Validate.
            bool isValid = true ? throw new NotImplementedException() 
                : false;
    
            if (isValid)
            {
                thenInvokeThis();
            }
            else
            {
                elseInvokeThis();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-11
      • 2012-09-20
      • 2016-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-25
      • 2021-03-18
      相关资源
      最近更新 更多