重构此代码以更好地利用 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<bool>
。如果调用 Func 时返回 false,则返回失败的结果,错误将采用第二个参数的值errorMessage
。
Map 的行为就像 OnSuccess,我相信可以公平地说您可以将其视为 OnSuccessThenMapTo 的简写。如果满足上述 2 中的条件,则返回 Ok 结果,并且映射使用新的 SomeObject 对象填充它。
【讨论】:
你知道是否有办法在多个确保条件失败时返回多个错误消息? @RikD 是的,很难在评论中给出示例,但您可能需要使用 Result.Combine。你会返回说 Result.Combine(",", result1, result2, ...)。第一个参数是您想要分隔错误的任何内容。它还接受一个结果数组。以上是关于重构此代码以更好地利用 CSharpFunctionalExtensions 库的主要内容,如果未能解决你的问题,请参考以下文章
重构此函数以在 if 语句 Javascript 内部和外部一致地使用“return”