2015-12-07 57 views
0

編輯: 將誰標記爲重複的問題。這個問題是關於如何創建一個深層副本。我的問題是如何確保在複製類元素列表時調用複製構造函數。帶有類元素的列表的深層副本

我試圖做一個包含自定義類元素的列表的深層副本。如果我有一個字符串列表,我可以只使用

List<string> secondList = new List<string>(firstList); 

,然後隨意修改在第二列表中的元素,而無需在firwst列表effeting的人。但是,當我嘗試對自定義類類型執行相同的操作時,兩個列表都會發生更改。爲了嘗試解決這個問題,我做了一個只有這門課的小測試程序。

class TestClass 
{ 
    public string name; 

    public TestClass(string n) 
    { 
     name = n; 
    } 

    public TestClass(TestClass original) 
    { 
     name = original.name; 
    } 
} 

我所有的程序會是這樣的

TestClass t = new TestClass("Name1"); 
List<TestClass> list1 = new List<TestClass>(); 
list1.Add(t); 

List<TestClass> list2 = new List<TestClass>(list1); 
list2[0].name = "Name2"; 

這代碼最後一行改變兩個列表,這是我做不希望第一個元素的名稱。

+6

嘗試:'列表2 = list1.Select(X =>新識別TestClass(X ))。ToList()' –

+2

[Deep cloning objects](可能的重複對象)(http://stackoverflow.com/questions/78536/deep-cloning-objects) – Ben

回答

2

這裏的問題是您的對象是引用類型,並且這些列表持有對這些對象的引用。

這意味着即使您的第二個列表具有來自第一個列表的引用的COPY,引用仍然指向原始對象。

爲了解決這個問題,您必須克隆列表中的引用,而不是克隆存儲在列表中的實際對象。

您已經定義了一個拷貝構造函數的類,所以你可以用它來使列表的深層副本如下:

var list2 = list1.Select(item => new TestClass(item)).ToList(); 
1

創建這一行代碼的參考:

List<TestClass> list2 = new List<TestClass>(list1); 

但是你不想使用Call-by-Reference。您需要按此方法撥打價值 。

所以在lambda表達式的工作代碼爲以下之一:

 TestClass t = new TestClass("Name1"); 
     List<TestClass> list1 = new List<TestClass>(); 
     list1.Add(t); 

     List<TestClass> list2 = new List<TestClass>(); 
     list2 = list1.Select(item => new TestClass(item)).ToList(); 
     list2[0].name = "Name2"; 

有樂趣...