我有以下结构,它应该允许我创建,然后修改时间和值属性,这将改变私有可变值x.Time_和x.Value _。
type TimeDataPoint =
struct
val mutable private Time_: DateTime
val mutable private Value_: double
new (time: DateTime, value: double) =
{
Time_ = time
Value_ = value
}
member public x.Time
with get() = x.Time_
and set(time: DateTime) = x.Time_ <- time
member public x.Value
with get() = x.Value_
and set(value: double) = x.Value_ <- value
end
但是,当我尝试在以后的代码中使用其中一个setter时:
let tdp = TimeDataPoint(DateTime.Now, 0.0)
tdp.Time <- DateTime.Now
我收到错误:
Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x=...'
这对我来说没有意义,因为变量已经是可变的,并且struct编译。我错过了什么?
修改
好的,我简化了我的例子,因为我认为这没关系,但我现在看到它确实如此。我实际上有一个TimeDataPoints的LinkedList,我试图改变一些节点的内容,所以我不能按照建议在本地声明它。这是我的代码:
let myList = LinkedList<TimeDataPoint>()
myList.AddFirst(TimeDataPoint(DateTime.Now, 0.0))
myList.First.Value.Value <- 1.0
我该如何解决这个问题?
答案 0 :(得分:3)
您还需要将tdp
标记为可变。剥离代码在下面,输出:
Ticks is 0
Ticks is 636028131920527873
正如所料。
module Mutation
open System
type TimeDataPoint =
struct
val mutable private Time_: DateTime
new (time: DateTime) =
{
Time_ = time
}
member public x.Time
with get() = x.Time_
and set(time: DateTime) = x.Time_ <- time
end
let usingTdp() =
let mutable tdp = TimeDataPoint()
printfn "Ticks is %i" tdp.Time.Ticks
tdp.Time <- DateTime.Now
printfn "Ticks is %i" tdp.Time.Ticks
在更新问题后进行编辑:正如评论中所提到的,如果您取消struct
这一事物,所有内容都会正常运行,例如:
type TimeDataPoint =
val mutable private _v: int
new (v: int) =
{
_v = v
}
member public this.Value
with get() = this._v
and set(v: int) = this._v <- v
let myList = LinkedList<TimeDataPoint>()
myList.AddFirst(TimeDataPoint(1)) |> ignore
myList.First.Value.Value <- 1
如果使用F#,你也可以考虑重新思考变异是否真的是你唯一的选择 - 我怀疑它是不是。
PS:如果您决定坚持使用变异对象,请考虑使用自动属性语法,该语法允许您将类定义缩短为:
type TimeDataPoint(v, d) =
member val Value: int = v with get, set
member val Time: DateTime = d with get, set