这是一个简单的C#结构,它对ctor参数进行了一些验证:
public struct Foo
{
public string Name { get; private set; }
public Foo(string name)
: this()
{
Contract.Requires<ArgumentException>(name.StartsWith("A"));
Name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
我已成功将其翻译成F#类:
type Foo(name : string) =
do
Contract.Requires<ArgumentException> (name.StartsWith "A")
member x.Name = name
Run Code Online (Sandbox Code Playgroud)
但是,我无法将其转换为F#中的结构:
[<Struct>]
type Foo =
val Name : string
new(name : string) = { do Contract.Requires<ArgumentException> (name.StartsWith "A"); Name = name }
Run Code Online (Sandbox Code Playgroud)
这给出了编译错误:
无效的记录,序列或计算表达式.序列表达式应为'seq {...}'形式
这不是有效的对象构造表达式.显式对象构造函数必须调用备用构造函数或初始化对象的所有字段,并指定对超类构造函数的调用.
我哪里做错了?
假设我有一个如此定义的记录......
type Employee = {Name : string; Salary : int}
Run Code Online (Sandbox Code Playgroud)
我想要另一种Salary固定的类型.我想能说...
type Manager = {Name: string; Salary : int = 250000}
Run Code Online (Sandbox Code Playgroud)
......但似乎我做不到.
我有什么选择来获得这种行为?
我更喜欢F#中的类记录,因为我不需要实现相等和哈希码.但是,它们似乎没有提供确保记录值不变量的工具.
例如,假设我正在为数独板建模.我可能写一个像这样的记录类型:
type Sudoku = { Values : Map<(int * int), int> }
let empty = { Values = Map.empty }
Run Code Online (Sandbox Code Playgroud)
现在的问题是我对Values地图有一些要求:
(x, y)必须x和y介于0和8,包容性使用类型,我可以在构造函数中检查这些,如果不满足则引发异常.这样,任何使用a的代码Sudoku都由构造函数保证满足不变量.
我如何通过记录实现这一目标?