2014-12-02 55 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