位置:首頁 > 軟件操作教程 > 編程開發(fā) > C# > 問題詳情

C# 給CardLib添加深度復(fù)制

提問人:劉團(tuán)圓發(fā)布時(shí)間:2020-12-07

    使用ICloneable接口,復(fù)制Caixl、Cards和Deck對(duì)象,這在某些撲克牌游戲中是有用的,因?yàn)樵谶@些游戲中不需要讓兩副撲克牌引用同—組Caid對(duì)象,但肯定會(huì)使一副撲克牌中的牌序與另一副牌的牌序相同。

    在ChllCardLib中,對(duì)Can!類執(zhí)行復(fù)制操作是很簡(jiǎn)單的,因?yàn)橹恍枰M(jìn)行淺度復(fù)制(Card只包含值類型的數(shù)據(jù),其形式為字段)。我們只需要對(duì)類定義進(jìn)行如下修改:

public class Card : ICloneable

{

    public object Clone() => MemberwiseClone();

ICloneable接口的這段實(shí)現(xiàn)代碼只是一個(gè)淺度復(fù)制,無法確定在Clone()方法中執(zhí)行了什么操作,但這己經(jīng)足以滿足我們的需要。

接著,需要對(duì)Cards集合類實(shí)現(xiàn)ICloneable接口。這個(gè)過程稍復(fù)雜些,因?yàn)樯婕暗綇?fù)制源集合中的每個(gè)Gmi對(duì)象,所以需要進(jìn)行深度復(fù)制:

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類上實(shí)現(xiàn)ICloneable接口。這里存在一個(gè)小問題:因?yàn)镃hi ICardLib中的Deck類無法修改它包含的撲克牌,所以沒有洗牌。例如,無法修改有給定牌序的Deck實(shí)例。為解決這個(gè)問題,為Deck類定義一個(gè)新的私有構(gòu)造函數(shù),在實(shí)例化Deck對(duì)象時(shí),可以給該函數(shù)傳遞一個(gè)特定的Cards集合。所以,在這個(gè)類中執(zhí)行復(fù)制的代碼如下所示:

public class Deck : ICloneable

{

    public object Clone()

    {

        Deck newDeck = new Deck(cards.Clone() as Cards); 

        return newDeck;

    }

    private Deck(Cards newCards) => cards = newCards;

再次用一些簡(jiǎn)單的客戶代碼進(jìn)行測(cè)試。與以前一樣,這些代碼應(yīng)放在客戶項(xiàng)目的MainO方法中,以便進(jìn)行測(cè)試:

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();

其輸出結(jié)果如圖所示。

image.png

繼續(xù)查找其他問題的答案?

相關(guān)視頻回答
回復(fù)(0)
返回頂部