• (原创)c#学习笔记10--定义类成员06--示例应用程序02--编写类库


    10.6.2  编写类库

      类和枚举都包含在一个类库项目 Ch10CardLib 中。这个项目将包含 4 个.cs 文件,Card.cs 包含Card类的定义,Deck.cs包含Deck类的定义,Suit.cs和Rank.cs文件包含枚举。

      1. Chapter10目录中创建一个新类库项目Ch10CardLib。从项目中删除Class1.cs。

      2. 添加:Suit.cs和Rank.cs文件,如下所示修改:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Ch10CardLib
    {
        public enum Rank
        {
            Ace = 1,
            Deuce,
            Three,
            Four,
            Five,
            Six,
            Seven,
            Eight,
            Nine,
            Ten,
            Jack,
            Queen,
            King,
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Ch10CardLib
    {
        public enum Suit
        {
            Club,
            Diamond,
            Heart,
            Spade,
        }
    }

      3. 添加Card类,代码如下:

    public class Card {
        public readonly Suit suit;
        public readonly Rank rank;
        
        public Card( Suit newSuit, Rank newRank ) {
            suit = newSuit;
            rank = newRank;
        }
        
        private Card() {
            
        }
        
        public override string ToString() {
            return "The " + rank + " of " + suit + "s";
        }
    }

      重写的ToString()方法将已存储的枚举值的字符串表示写入到返回的字符串中, 非默认的构造函数初始化suit和rank字段的值。

      3. 添加Deck类

        Deck类需要使用类图定义的如下成员:

          Card[]类型的私有字段cards。

          公共的默认构造函数。

          公共方法GetCard(),它带有一个int参数cardNum,并返回一个Card类型的对象。

          公共方法Shuffle(),它不带参数,返回void。

      代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Ch10CardLib
    {
        public class Deck
        {
            private Card[] cards;
            public Deck()
            {
                cards = new Card[52];
                for (int suitVal = 0; suitVal < 4; ++suitVal)
                {
                    for (int rankVal = 1; rankVal < 14; ++rankVal)
                    {
                        cards[suitVal * 13 + rankVal - 1] = new Card((Suit)suitVal, (Rank)rankVal);
                    }
                }
            }
    
            public Card GetCard(int cardNum)
            {
                if (cardNum >= 0 && cardNum <= 51)
                {
                    return cards[cardNum];
                }
                else
                {
                    throw (new System.ArgumentOutOfRangeException("cardNum", cardNum, "Value must be between 0 and 51."));
                }
            }
    
            public void Shuffle()
            {
                Card[] newDeck = new Card[52];
                bool[] assigned = new bool[52];
                Random sourceGen = new Random();
                for (int i = 0; i < 52; ++i)
                {
                    int destCard = 0;
                    bool foundCard = false;
                    while (false == foundCard)
                    {
                        destCard = sourceGen.Next(52);
                        if (false == assigned[destCard])
                        {
                            foundCard = true;
                        }
                    }
                    assigned[destCard] = true;
                    newDeck[destCard] = cards[i];
                }
                newDeck.CopyTo(cards, 0);
            }
        }
    }

      Shuffle()方法。这个方法创建一个临时的扑克牌数组,并把扑克牌从现有的cards数组随机复制到这个数组中。这个函数的主体是一个从 0~51 的循环,在每次循环时,都会使用.NET Framework中的System.Random类的实例生成一个0~51之间的随机数。进行了实例化后,这个类的对象使用方法Next(X)生成一个介于0~X之间的随机数。有了一个随机数后,就可以使用它作为临时数组中Card对象的索引,以便复制cards数组中的扑克牌。

      为了记录已赋值的扑克牌,我们还有一个bool变量的数组,在复制每张牌时,把该数组中的值指定为 true。在生成随机数时,检查这个数组,看看是否已经把一张牌复制到临时数组中由随机数指定的位置上了,如果已经复制好了,就将生成另一个随机数。

      这不是完成该任务的最高效的方式,因为生成的许多随机数都可能找不到空位置以复制扑克牌。但是,它仍能完成任务,而且很简单,因为C#代码的执行速度很快,我们几乎觉察不到延迟。

      这个方法的最后一行使用System.Array类的CopyTo()方法(在创建数组时使用),把newDeck中的每张扑克牌复制回 cards 中。也就是说,我们使用同一个 cards 对象中的同一组 Card 对象,而不是创建新的实例。如果改用cards = newDeck,就会用另一个对象替代cards引用的对象实例。如果其他地方的代码仍保留对原cards实例的引用,就会出问题——不会洗牌。

      至此,就完成了类库代码。

  • 相关阅读:
    echart tooltip.formatter提示只显示x轴(时间)
    Install fail! Error: EBUSY: resource busy or locked
    vue v-model绑定值为obj不起作用
    浅谈JS的继承
    总结一下最近对nodejs 和 mongodb 的学习
    JavaScript30-7 数组的一些基本方法
    Vue-router 的练习
    JavaScprit30-6 学习笔记
    JavaScprit30-5 学习笔记
    JavaScript 30
  • 原文地址:https://www.cnblogs.com/wodehao0808/p/4969474.html
Copyright © 2020-2023  润新知