C#卡牌游戏程序异常:Deck_Display始终显示最后一张卡牌
问题:C#卡牌游戏牌组显示异常,仅显示最后一张卡牌
我正在练习用C#编写一款简单卡牌游戏,在创建牌组(Deck)时遇到问题。我将Card类的对象存储在名为Deck的Dictionary中,但调用Deck_Display方法时,每次都只会显示牌组中的最后一张卡牌。不过如果将Deck_Display的代码复制到创建Deck的循环中,却能正常显示所有卡牌。
相关代码如下:
internal class Deck { public Dictionary<string, Card> deck = new Dictionary<string, Card>(); public Deck() { int k = 0; for (int i = 0; i < 13; i++) { for (int j = 0; j < 4; j++) { deck.Add(String.Format("card{0}", k.ToString()), new Card((i+1), (j+1))); } } } public void Deck_Display() { for (int i = 0; i < 52; i++) { Card aaa = deck[String.Format("card{0}", i.ToString())]; Console.WriteLine($"{aaa.GetSuit()}, {aaa.GetRank()}"); Console.WriteLine("\n"); } } }
internal class Program { static void Main() { Deck bruh = new Deck(); bruh.Deck_Display(); } } internal class Card { public static int suit; public static int rank; public Card(int suit1, int rank1) { suit = suit1; rank = rank1; } public int GetSuit() { return suit; } public int GetRank() { return rank; } }
问题根源
你的Card类中suit和rank字段被声明为static(静态)。静态字段属于类本身,而非类的实例对象——所有Card实例会共享这两个字段的值,每次创建新Card对象时都会覆盖字段内容,最终所有实例的GetSuit()和GetRank()都会返回最后一次赋值的结果。
在创建Deck的循环内直接显示时,是在字段被覆盖前读取了当前值,所以能正常显示;但循环结束后调用Deck_Display时,所有实例都指向最后一次设置的静态字段值。
修复方案
将Card类中的静态字段改为实例字段,去掉static关键字即可:
internal class Card { // 移除static关键字,改为实例字段 public int suit; public int rank; public Card(int suit1, int rank1) { suit = suit1; rank = rank1; } public int GetSuit() { return suit; } public int GetRank() { return rank; } }
额外优化建议
- 封装字段:遵循面向对象封装原则,将字段改为私有,用属性对外暴露:
internal class Card { public int Suit { get; } public int Rank { get; } public Card(int suit, int rank) { Suit = suit; Rank = rank; } }
此时Deck_Display可直接调用属性:Console.WriteLine($"{aaa.Suit}, {aaa.Rank}");,无需额外的Get方法。
- 修复牌组键重复问题:Deck构造函数中的
k变量未自增,会导致添加重复键card0抛出异常,需在每次Add后执行k++:
public Deck() { int k = 0; for (int i = 0; i < 13; i++) { for (int j = 0; j < 4; j++) { deck.Add(String.Format("card{0}", k.ToString()), new Card((i+1), (j+1))); k++; // 添加该行实现键的唯一标识 } } }
内容的提问来源于stack exchange,提问作者Alex Tonev
相关产品推荐
相关产品推荐

