You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
    }
}

额外优化建议

  1. 封装字段:遵循面向对象封装原则,将字段改为私有,用属性对外暴露:
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方法。

  1. 修复牌组键重复问题: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 02:13:35