我完全不知道为什么这段代码不会在一系列类型中变异成员变量:
for p in prescrs do
p.ATC <- "A"
for c in p.Drug.Components do
for s in c.Substances do
s.DoseTotal.Adjust <- adjustKg
s.DoseTotal.Time <- "DAY"
s.DoseTotal.Unit <- s.DrugConcentration.Unit
s.DoseRate.Adjust <- adjustKg
s.DoseRate.Time <- "DAY"
s.DoseRate.Unit <- s.DrugConcentration.Unit
prescrs是一系列Prescriptions,是一个非常简单的POCO&#39;定义为具有成员值的类型。我不知道为什么这不起作用。
我尝试了一个简单的测试用例,如:
type IterTest () =
member val Name = "" with get, set
member val IterTests = [] |> List.toSeq : IterTest seq with get, set
let iterseq =
[
new IterTest(Name = "Test1")
new IterTest(Name = "Test2")
]
|> List.toSeq
iterseq |> Seq.iter(fun x -> x.IterTests <- iterseq)
iterseq |> Seq.iter(fun x ->
x.IterTests
|> Seq.iter(fun x' -> x'.Name <- "itered"))
但这里的结果与预期一致。所以,甚至无法重现我的问题???
找到解决方案(没有真正理解上面的问题)。当我第一次将prescrs序列转换为如下列表时:
let prescrs = prescrs |> Seq.toList
然后执行命令式循环,属性确实会发生变异。
答案 0 :(得分:4)
试试这个样本:
type Mutable() =
member val Iterated = false with get, set
let muts = Seq.init 5 (fun _ -> printfn "init"; Mutable())
let muts2 = muts // try again with let muts2 = muts |> List.ofSeq
printfn "Before iter"
for a in muts2 do
printfn "iter"
a.Iterated <- true
printfn "After iter"
muts2 |> List.ofSeq
并检查iter
和init
是如何交错的。
Seqs
是懒惰的,但计算后不会缓存。因此,即使您强制尝试改变prescrs
序列中的某些元素,一旦再次拉出prescrs
,这一切都会消失。如果在进行变异之前将prescrs
更改为类似列表的具体集合类型,则不再遇到同样的问题。请注意,如果您拥有seq内seq内的seq,事情可能会变得更加棘手。
最好的办法是尽量避免突变。