2014-12-02 24 views
2

我的损失是完全为什么这个代码不类型的序列变异的成员变量:完全丧失试图突变序列财产

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是方的序列这是一个非常简单的'POCO'定义为具有成员值的类型。我不知道为什么这不起作用。

我想一个简单的测试案例,如:

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

“这不行”是什么意思? prescrs是如何制作的? (顺便说一下,让prescrs = prescrs |> Seq.toList'是一个转换,而不是一个演员。) – ildjarn 2014-12-02 00:53:16

+0

@ildjarn我的意思是,属性没有改变。在第二个例子中,属性确实改变了。这两个例子都是对一个序列的迭代,所以我期待着相同的行为。 – halcwb 2014-12-02 08:17:35

+0

但你怎么知道价值没有改变?也许你的测试是有缺陷的...... _ prescrs是如何产生的?_当你没有显示足够的相关上下文代码时,你期望获得帮助吗? – ildjarn 2014-12-02 08:22:54

回答

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 

,并检查如何iterinit交错。

Seqs是懒惰的,但一旦计算就不会被缓存。因此,即使您试图改变prescrs序列中的某些元素,一旦您再次拉动prescrs,它也会全部消失。如果在做突变之前将prescrs更改为列表等具体集合类型,则不会再遇到同样的问题。请注意,如果你所拥有的是seq中的seq内部的seq,事情可能会变得更加棘手。

最好的想法是尽量避免突变。

+0

谢谢,非常好的解释,明白了。 – halcwb 2014-12-02 08:26:17