位置:首页 > 软件操作教程 > 编程开发 > C# > 问题详情

C# 给CardLib添加深度复制

提问人:刘团圆发布时间:2020-12-07

    使用ICloneable接口,复制Caixl、Cards和Deck对象,这在某些扑克牌游戏中是有用的,因为在这些游戏中不需要让两副扑克牌引用同—组Caid对象,但肯定会使一副扑克牌中的牌序与另一副牌的牌序相同。

    在ChllCardLib中,对Can!类执行复制操作是很简单的,因为只需要进行浅度复制(Card只包含值类型的数据,其形式为字段)。我们只需要对类定义进行如下修改:

public class Card : ICloneable

{

    public object Clone() => MemberwiseClone();

ICloneable接口的这段实现代码只是一个浅度复制,无法确定在Clone()方法中执行了什么操作,但这己经足以满足我们的需要。

接着,需要对Cards集合类实现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类上实现ICloneable接口。这里存在一个小问题:因为Chi ICardLib中的Deck类无法修改它包含的扑克牌,所以没有洗牌。例如,无法修改有给定牌序的Deck实例。为解决这个问题,为Deck类定义一个新的私有构造函数,在实例化Deck对象时,可以给该函数传递一个特定的Cards集合。所以,在这个类中执行复制的代码如下所示:

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

其输出结果如图所示。

image.png

继续查找其他问题的答案?

相关视频回答
回复(0)
返回顶部