重构此代码以更好地利用 CSharpFunctionalExtensions 库

Posted

技术标签:

【中文标题】重构此代码以更好地利用 CSharpFunctionalExtensions 库【英文标题】:Refactoring this code to make better use of the CSharpFunctionalExtensions Library 【发布时间】: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."
     );

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

【问题讨论】:

【参考方案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, ...)。第一个参数是您想要分隔错误的任何内容。它还接受一个结果数组。

以上是关于重构此代码以更好地利用 CSharpFunctionalExtensions 库的主要内容,如果未能解决你的问题,请参考以下文章

重构此函数以在 if 语句 Javascript 内部和外部一致地使用“return”

如何更好地重构可以在 java 中返回 null 的方法链?

Eclipse 重构

重构改善代码的既有设计

如何重构此搜索过滤器查询?

Flink 1.5版本网络栈重构技术分析