2017-02-09 59 views
1

我已經構建了下面的簡單示例來說明我在我的實際代碼中所遇到的問題,它比較複雜。列表中每個迭代覆蓋列表中的對象屬性

首先,我簡單的類:

public class InnerTemp { 
    public int A { get; set; } 
    public int B { get; set; } 
    public int C { get; set; } 
} 

public class OuterTemp { 
    public List<InnerTemp> InnerTemps { get; set; } 
} 

和實現:

var outerTemps = new List<OuterTemp>(); 
var innerTemps = new List<InnerTemp>(); 
innerTemps.Add(new InnerTemp() { A = 1, B = 2, C = 3 }); 
innerTemps.Add(new InnerTemp() { A = 4, B = 5, C = 6 }); 

for(int i = 1; i < 5; i++) { 
     foreach(InnerTemp innerTemp in innerTemps) { 
      innerTemp.A += i; 
      innerTemp.B += i; 
      innerTemp.C += i; 
     } 

     var outerTemp = new OuterTemp() 
     { 
      InnerTemps = innerTemps 
     }; 

     outerTemps.Add(outerTemp); 
} 

我將在最後一行我的斷點,右大括號。按照預期,在第一次迭代中,outerTemps[0].InnerTemps[0].A的值爲2。但是在第二個循環中,outerTemps[0].InnerTemps[0].A的值變成了4,這讓我感到困惑。第一個對象的屬性A僅僅因爲添加了另一個對象而被踩踏。我完全認爲outerTemps[1].InnerTemps[0].A是不同的,但爲什麼我的原始財產跺腳?

如何更改此設置,以便每次將新對象添加到集合時都不會覆蓋先前的對象屬性?

+0

你想要什麼'outerTemps [0] .InnerTemps [0] .A'在第二個循環? – IllidanS4

+2

你應該看看[淺vs深層複製](http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy) 。您正在複製對「innerTemps」的引用,而不是對所有元素進行深層複製。這會導致爲每個outerTemp對象修改相同的InnertTemp引用。 –

+0

它很明顯,你正在修改每個迭代中的相同列表。您需要創建一個InnerTemp的新列表,其中包含外部for循環的每次迭代中的所有對象的深層副本。 –

回答

2

正如我在我的評論中提到的,您正在創建innerTemps列表的淺表副本,該副本會導致複製引用而不是創建列表中每個InnerTemp對象的深度副本。

如果您希望在新創建的OuterTemp中單獨使用InnerTemp對象,這些對象將分別進行跟蹤和修改,您必須創建它們的深層副本。

每建議here我會建議您InnerTemp類創建一個Copy方法:

public class InnerTemp 
{ 
    public int A { get; set; } 
    public int B { get; set; } 
    public int C { get; set; } 

    public static InnerTemp Copy(InnerTemp source) 
    { 
     return new InnerTemp { A = source.A, B = source.B, C = source.C }; 
    } 
} 

,並使用創建的每個OuterTemp新的列表時:

var outerTemp = new OuterTemp() 
{ 
    InnerTemps = innerTemps.Select(InnerTemp.Copy).ToList(); 
}; 

這將防止outerTemps列表中的值被循環計數器修改。請注意,.ToList()通過評估Select enumerable並返回一個新列表隱式創建深層副本,因此您不必擔心導致問題的列表引用。

+0

謝謝你的Moffat。 – HerrimanCoder

相關問題