2013-06-01 34 views
4

我不知道這些東西在內部存儲器/處理器中是如何發生的。管理列表項的困難

我創建了一個名爲Block的類,它具有的位置。我還有一個List<Block>來存儲我的塊。

首先,我添加了一個阻止該名單:

blocks.Add(new Block()); 

然後,我想克隆該塊,讓我有我的列表中不同位置的兩個獨立的模塊:

Block clonedBlock = blocks[0]; 
blocks.Add(clonedBlock); 

但是當我改變新創建的塊的位置時,我也改變了第一個塊的位置。

它爲什麼這樣做,有什麼辦法可以防止這種情況?

順便說一下,我注意到列表似乎有一些奇怪的行爲。 例如,在這種情況下:

List<Block> list01 = new List<Block>(); 
[... add some blocks to that list ...] 
List<Block> list02 = list01; // also tried: List<Block> list02 = list01.ToList(); 
[... change item in list01 ...] --> also changes that item in list02 

這讓我猜,僅列出包含類似指針,當我試圖「克隆」一個塊,我只複製指針,但位置它指向停留在相同。同樣的問題:有什麼辦法可以防止這種情況發生?

編輯:解:Object.MemberwiseClone()- Method

+0

你的猜測基本上是正確的。類是引用類型,所以你的行'Block clonedBlock = blocks [0];'將'clonedBlock'設置爲與'blocks [0]'相同的地址。對其中一項做出的更改將反映在另一項中。你最好創建一個'Block'的新實例並將其添加到列表中,除非有某些原因想要複製另一個塊並簡單地改變它的位置? – Tim

+0

解決這個問題的另一種方法是實現一個深層副本(我認爲這是一個術語 - 自從我在C++中做了任何事情以來已經有數年了)。創建一個新的'Block'實例,然後將原始值複製到新的實例中。 – Tim

+0

感謝您的快速回復! 這將是可能的,只是創建一個Block的新實例,但這不會是一個好的解決方案,因爲我的列表並不真正存儲Block類型的塊,而是Block的子類塊,所以我首先需要弄清楚,哪個孩子班級等等......:/ 真的沒有辦法只是「克隆」/「複製」一個塊嗎? – user2442333

回答

3

你的猜測是基本上是正確的。類是引用類型,所以你的行Block clonedBlock = blocks [0];將克隆的塊設置爲與塊[0]相同的地址。對其中一項做出的更改將反映在另一項中。您最好創建一個Block的新實例並將其添加到列表中,除非有某些原因需要複製另一個塊並更改其位置。

解決這個問題的一種方法是實現一個深層副本(我認爲這個術語 - 自從我在C++中做了任何事情以來已經有多年了)。創建一個Block的新實例,然後將原始值複製到新的實例中。你可以看看實現ICloneable,或者簡單地編寫你自己的拷貝方法(實際上,如果你實現了ICloneable,你仍然在編寫你自己的拷貝方法 - 界面只是確保使用它的類實現Clone方法。或淺的取決於實施者)。

另外,請看Object.MemberwiseClone方法。 Object.MemberwiseClone做了一個淺拷貝,但是在Examples部分中有一個做淺和深拷貝的例子。

+0

再次感謝,Object.MemberwiseClone() - 方法正是我一直在尋找! :) – user2442333

+0

不客氣。快樂的編碼! – Tim