C# 給CardLib添加深度復制
使用ICloneable接口,復制Caixl、Cards和Deck對象,這在某些撲克牌游戲中是有用的,因為在這些游戲中不需要讓兩副撲克牌引用同—組Caid對象,但肯定會使一副撲克牌中的牌序與另一副牌的牌序相同。
在ChllCardLib中,對Can!類執(zhí)行復制操作是很簡單的,因為只需要進行淺度復制(Card只包含值類型的數(shù)據,其形式為字段)。我們只需要對類定義進行如下修改:
public class Card : ICloneable
{
public object Clone() => MemberwiseClone();
ICloneable接口的這段實現(xiàn)代碼只是一個淺度復制,無法確定在Clone()方法中執(zhí)行了什么操作,但這己經足以滿足我們的需要。
接著,需要對Cards集合類實現(xiàn)ICloneable接口。這個過程稍復雜些,因為涉及到復制源集合中的每個Gmi對象,所以需要進行深度復制:
public class Cards : CollectionBase, ICloneable
{
public object Clone()
{
Cards newCards = new Cards();
foreach (Card sourceCard in List)
{
newCards.Add((Card)sourceCard.Clone());
}
return newCards;
}
最后,需要在Deck類上實現(xiàn)ICloneable接口。這里存在一個小問題:因為Chi ICardLib中的Deck類無法修改它包含的撲克牌,所以沒有洗牌。例如,無法修改有給定牌序的Deck實例。為解決這個問題,為Deck類定義一個新的私有構造函數(shù),在實例化Deck對象時,可以給該函數(shù)傳遞一個特定的Cards集合。所以,在這個類中執(zhí)行復制的代碼如下所示:
public class Deck : ICloneable
{
public object Clone()
{
Deck newDeck = new Deck(cards.Clone() as Cards);
return newDeck;
}
private Deck(Cards newCards) => cards = newCards;
再次用一些簡單的客戶代碼進行測試。與以前一樣,這些代碼應放在客戶項目的MainO方法中,以便進行測試:
Deck deckl = new Deck();
Deck deck2 = (Deck)deckl.Clone();
WriteLine($"The first card in the original deck is: {deckl.GetCard(0)}");
WriteLine($"The first card in the cloned deck is: {deck2.GetCard{0)}");
deckl.Shuffle();
WriteLine ("Original deck shuffled.");
WriteLine($"The first card in the original deck is: {deckl.GetCard(0)}");
WriteLine($"The first card in the cloned deck is: {deck2.GetCard(0)}");
ReadKey();
其輸出結果如圖所示。
點擊加載更多評論>>