如何优化基于CSharpFunctionalExtensions库的Create方法实现?
如何用CSharpFunctionalExtensions的链式调用重构Result创建方法?
我目前使用Vladimir Khorikov开发的CSharpFunctionalExtensions库编写了一个对象创建方法,实现如下:
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.");
这个方法能满足需求,但我觉得没有充分利用库的链式调用能力。我希望用类似以下伪代码的链式方式重构,但不清楚具体的API使用方式:
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." );
我确定这个库支持这类链式实现,恳请各位指导具体的重构方法。
你完全可以通过CSharpFunctionalExtensions提供的Ensure和Bind/Map方法来实现这种流畅的链式调用,这几个方法正是为参数验证、值转换这类场景设计的,完美匹配你的需求。
这里提供两种重构方案,你可以根据可读性偏好选择:
方案一:用Map整合解析逻辑
public static Result<SomeObject> Create(string value) => Result.Ok(value) .Ensure(v => v.Length <= 10, $"{nameof(value)} must be less than 10 characters long.") .Map(v => { if (!int.TryParse(v, out int result)) return Result.Fail<SomeObject>($"{nameof(value)} must be a number."); return Result.Ok(new SomeObject(result)); });
方案二:用Bind拆分解析步骤(更纯粹的链式风格)
public static Result<SomeObject> Create(string value) => Result.Ok(value) .Ensure(v => v.Length <= 10, $"{nameof(value)} must be less than 10 characters long.") .Bind(v => { return int.TryParse(v, out int result) ? Result.Ok(result) : Result.Fail<int>($"{nameof(value)} must be a number."); }) .Map(result => new SomeObject(result));
核心方法说明:
Result.Ok(value):把输入的value包装成成功的Result<string>,作为链式调用的起点。Ensure:用来做条件验证——如果条件不满足,直接返回带错误信息的失败Result;满足的话,就把原有的成功Result传递到下一个步骤。Bind:处理可能失败的转换操作(比如这里的字符串转int),它会自动处理失败分支:只要前一步或当前Bind返回失败,整个链式调用就会终止并返回这个失败结果。Map:用来做安全的类型转换,只有当前面所有步骤都成功时才会执行,把上一步的成功值转换成你需要的最终类型。
这种写法彻底替代了嵌套的三元表达式,代码逻辑更线性,可读性更强,也完全贴合CSharpFunctionalExtensions的设计初衷。
内容的提问来源于stack exchange,提问作者Scott Baker
相关产品推荐
相关产品推荐

