我正在编写一个有两个构造函数的泛型类:第一个初始化每个字段,第二个(无参数)不应该初始化任何字段.
我发现实现此目的的唯一方法是使用"空"参数调用主构造函数,即Guid.Empty和null.除了没有看到我未经训练的眼睛的良好功能风格,这意味着我必须对a' : null第二个参数设置约束,我不想要:
type Container<'a when 'a : null>(id : Guid, content : 'a) =
let mutable _id = id
let mutable _content = content
new() = Container<'a>(Guid.Empty, null)
member this.Id
with get() = _id
and set(value) = _id <- value
member this.Content
with get() = _content
and set(value) = _content <- value
Run Code Online (Sandbox Code Playgroud)
我看到两种解决方法:
defaultc#关键字而不是null(F#中存在这样的东西?)实现这个课程的最佳方法是什么?
F#模拟default是Unchecked.default<_>.也可以使用未初始化的显式字段:
type Container<'a>() =
[<DefaultValue>]
val mutable _id : Guid
[<DefaultValue>]
val mutable _content : 'a
new (id, content) as this =
new Container<'a>() then
this._id <- id
this._content <- content
Run Code Online (Sandbox Code Playgroud)
但是,总的来说,你的整体方法对于F#来说有点单一.通常,您使用简单的记录类型(可能使用静态方法来创建未初始化的容器,尽管这似乎有可疑的好处):
type 'a Container = { mutable id : Guid; mutable content : 'a } with
static member CreateEmpty() = { id = Guid.Empty; content = Unchecked.defaultof<_> }
Run Code Online (Sandbox Code Playgroud)
在许多情况下,您甚至可以使用不可变记录类型,然后使用记录更新语句生成具有更新值的新记录:
type 'a Container = { id : Guid; content : 'a }
[<GeneralizableValue>]
let emptyContainer<'a> : 'a Container =
{ id = Guid.Empty;
content = Unchecked.defaultof<_> }
let someOtherContainer = { emptyContainer with content = 12 }
Run Code Online (Sandbox Code Playgroud)