我正在尝试在 F# 中构建一个类型,当我获得该类型的对象时,我可以确定它处于有效状态。
该类型称为JobId
它只持有一个Guid
.
业务规则是:它必须是一个 Guid - 但不能是空的 Guid。
我已经在 C# 中实现了该类型,但现在我想将其移植到 F# 类库。
这是 C# 类型:
public sealed class JobId
{
public string Value { get; }
private JobId(string value)
=> Value = value;
public static JobId Create()
=> new JobId(Guid.NewGuid().ToString("N"));
public static Option<JobId> Create(Guid id)
=> id == Guid.Empty
? None
: Some(new JobId(id.ToString("N"));
public static Option<JobId> Create(string id)
{
try
{
var guid = new Guid(id);
return Create(guid);
}
catch (FormatException)
{
return None;
}
}
}
那么如何在 F# 中构建它呢?谢谢!
更新1:
我尝试将其实现为受歧视的联合类型,如下所示:
type JobId =
| JobId of string
但问题是,我无法用这种方法定义任何业务规则。
所以最后的问题是:如何确保string
in JobId
存在于一个
特定格式?
我已经调整了 Tomas 的答案,使用 DU 而不是类来保持适当的平等和比较,从而允许JobId
例如,作为分组键按预期工作。
[<AutoOpen>]
module JobId =
open System
type JobId = private JobId of string with
static member Create() = JobId(Guid.NewGuid().ToString("N"))
static member Create(id:Guid) =
if id = Guid.Empty then None
else Some(JobId(id.ToString("N")))
static member Create(id:string) =
try JobId.Create(Guid(id))
with :? FormatException -> None
您必须将类型放入模块内,然后您无法直接在该模块外部访问 DU 构造函数:
JobId.Create (System.Guid.NewGuid()) // Some (JobId "1715d4ae776d441da357f0efb330be43")
JobId.Create System.Guid.Empty // None
JobId System.Guid.Empty // Compile error
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)