2017-06-02 109 views
4

所以我需要一個深度克隆的方法。我想要一張卡片清單等於另一張卡片清單,但是我還想修改其中一個克隆。列表有沒有更好的深層克隆方法?

我做了一個方法來複制列表如下:

public List<Card> Copy(List<Card> cards) 
    { 
     List<Card> clone = new List<Card>(); 
     foreach (var card in cards) 
     { 
      clone.Add(card); 
     } 
     return clone; 
    } 

,並使用它像這樣:

 _cards = new List<Card>(); 
     _thrownCards = new List<Card>(); 

     _cards = Copy(_thrownCards); 
     _thrownCards.Clear(); 

我不是在C#中經驗豐富,但不知何故,我的直覺告訴我,我的複製方法可以變得更簡單。沒有其他方法可以深入複製列表嗎?我嘗試使用MemberWiseClone,但它只是創建對同一個對象的引用,而不是克隆它(也許我錯誤地解釋了MemberWiseClone方法)。

有沒有人有任何提示如何簡單地克隆一個列表對象?

+2

您可以克隆用'名單cards.ToList()'但如果'Card'是引用類型,則需要克隆每個列表元素以獲得深層副本。 – Lee

+1

你的方法不是深度克隆,因爲所有'Card'實例都沒有被克隆,只是被複制到另一個列表中(假設它們不是結構體)。 – Evk

+0

我只想指出,由於您的複製函數創建並返回'新列表()',您實際上並不需要首先初始化_cards。你可以像這樣使用你的函數:'_thrownCards = new List (); ...; _cards =複製(_thrownCards); _thrownCards.Clear();'另外,你在Copy函數中實際做的是一個淺層克隆。這裏有一個[Stackoverflow的問題](https://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy)關於兩者之間的區別。 – ashbygeek

回答

5

這不是真正的深拷貝,因爲Card實例仍然是相同的,只是列表不同。可以使用這個簡單得多:

List<Card> cloneList = cards.ToList(); 

你需要「複製」,以及在Card實例的所有特性:

public List<Card> Copy(List<Card> cards) 
{ 
    List<Card> cloneList = new List<Card>(); 
    foreach (var card in cards) 
    { 
     Card clone = new Card(); 
     clone.Property1 = card.Property1; 
     // ... other properties 
     cloneList.Add(clone); 
    } 
    return cloneList; 
} 

你可能還提供了創建一個給定的克隆工廠方法Card例如:

public class Card 
{ 
    // ... 

    public Card GetDeepCopy() 
    { 
     Card deepCopy = new Card(); 
     deepCopy.Property1 = this.Property1; 
     // ... 
     return deepCopy; 
    } 
} 

那麼你就封裝這種邏輯在一個地方,你甚至可以訪問private成員(字段,親perties,構造函數)。更改上面的Copy方法行:

cloneList.Add(card.GetDeepCopy()); 
+1

你會推薦將複製方法放在'Card'本身嗎? 'cloneList.Add(card.DeepCopy())' –

+0

@TimSchmelter對不起,得到了一個錯誤,並曲解了我自己的結構。這工作得很好,所以我將其標記爲解決方案! – Jesper

0

如何像

List<Card> _cards = _thrownCards.ConvertAll(Card => new Card(<card parameters here>)); 
1

有着深厚的副本,就需要有這樣的事情:

public List<Card> Copy(List<Card> cards) 
{ 
    List<Card> clone = new List<Card>(); 
    foreach (var card in cards) 
    { 
     clone.Add(new Card 
     { 
      property1 = card.property1; 
      property2 = card.property2; // and so on 
     }); 
    } 
    return clone; 
} 

當然如果property1property2也是引用類型的對象,那麼您將不得不深入。

0

不像當我們複製只引用

public List<Card> Copy(List<Card> cards) { 
    return cards.ToList(); 
} 

複製情況下,我們有克隆每個項目副本:

public List<Card> Copy(List<Card> cards) { 
    return cards 
    .Select(card => new Card() { 
     //TODO: put the right assignment here 
     Property1 = card.Property1, 
     ... 
     PropertyN = card.PropertyN, 
    }) 
    .ToList(); 
}