F#struct构造函数中的参数validation

这是一个简单的C#结构,它对ctor参数进行了一些validation:

public struct Foo { public string Name { get; private set; } public Foo(string name) : this() { Contract.Requires(name.StartsWith("A")); Name = name; } } 

我已成功将其翻译成F#类:

 type Foo(name : string) = do Contract.Requires (name.StartsWith "A") member x.Name = name 

但是,我无法将其转换为F#中的结构:

 [] type Foo = val Name : string new(name : string) = { do Contract.Requires (name.StartsWith "A"); Name = name } 

这会产生编译错误:

无效的记录,序列或计算表达式。 序列表达式应为’seq {…}’forms

这不是有效的对象构造表达式。 显式对象构造函数必须调用备用构造函数或初始化对象的所有字段,并指定对超类构造函数的调用。

我已经看过这个和这个,但它们不包括参数validation。

我哪里做错了?

初始化结构后,您可以使用then block。 在构造函数中执行副作用部分的第一个链接中描述了类,但它也适用于结构。

 [] type Foo = val Name : string new(name : string) = { Name = name } then if name.StartsWith("A") then failwith "Haiz" 

更新:

更接近你的例子的另一种方法是使用; (顺序组合)和括号组合表达式:

 [] type Foo = val Name : string new(name : string) = { Name = ((if name.StartsWith("A") then failwith "Haiz"); name) } 

如果你想避免显式字段( valthen两个相对深奥的特性,你可以使用静态Create方法并坚持更常见的类型定义语法:

 [] type Foo private (name: string) = member x.Name = name static member Create(name: string) = Contract.Requires (name.StartsWith "A") Foo(name)