【问题标题】:Refactoring this code to make better use of the CSharpFunctionalExtensions Library重构此代码以更好地利用 CSharpFunctionalExtensions 库
【发布时间】:2020-06-30 17:25:04
【问题描述】:

我有以下使用CSharpFunctionalExtensions library by Vladimir Khorikov的方法:

public static Result<SomeObject> Create(string value) =>
    value.Length > 10
        ? Result.Fail<SomeObject>($"{nameof(value)} must be less than 10 characters long.")
        : int.TryParse(value, out int result)
            ? Result.Ok(new SomeObject(result))
            : Result.Fail<SomeObject>($"{nameof(value)} must be a number.");

它做我想做的事,但我对我的实现不满意。感觉我并没有充分利用图书馆及其功能 - 但尽管我进行了研究,但我无法找到更好的方法。我觉得我应该以某种方式将验证调用包装在 Result.OnSuccess() 中,但那些不返回 Result,它们返回 bool 值。

我正在尝试做类似这样的伪代码:

public static Result<SomeObject> Create(string value) =>
    Result
      .Is(
         () => !(value.Length > 10, // success criteria
         value, // success value
         $"{nameof(value)} must be less than 10 characters long." // Result.Fail
     ).Is( 
          () => int.TryParse(value, out int result),
          result, // changing the success value to an int
          $"{nameof(value)} must be a number."
     );

我很确定图书馆已经支持我正在尝试做的事情,但我正在为“如何做”而苦苦挣扎。非常感谢任何帮助。

【问题讨论】:

    标签: c# functional-programming csharpfunctionalextensions


    【解决方案1】:

    如何使用 ensure 和 map。像这样

    public static Result<SomeObject> Create(string value)
    {
        int result = 0;
    
        return Result.Ok()
            .Ensure(() => value.Length <= 10,
                    errorMessage: $"{nameof(value)} must be less than 10 characters long.")
            .Ensure(() => int.TryParse(value, out result),
                    errorMessage: $"{nameof(value)} must be a number.")
            .Map(() => new SomeObject(result));
    }
    

    确保这里有 2 个参数。第一个是Func&lt;bool&gt;。如果调用 Func 时返回 false,则返回失败的结果,错误将采用第二个参数的值errorMessage

    Map 的行为就像 OnSuccess,我相信可以公平地说您可以将其视为 OnSuccessThenMapTo 的简写。如果满足上述 2 中的条件,则返回 Ok 结果,并且映射使用新的 SomeObject 对象填充它。

    【讨论】:

    • 你知道是否有办法在多个确保条件失败时返回多个错误消息?
    • @RikD 是的,很难在评论中给出示例,但您可能需要使用 Result.Combine。你会返回说 Result.Combine(",", result1, result2, ...)。第一个参数是您想要分隔错误的任何内容。它还接受一个结果数组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 1970-01-01
    相关资源
    最近更新 更多