C#不能保存struct变量的值

时间:2012-01-08 00:38:15

标签: c# struct public

我正在尝试编写一个框架程序,允许您玩德州扑克。我遇到函数hasPair时遇到问题,它决定CurrentPlayer是否有一对:

  public bool hasPair(Player CurrentPlayer)
        {
            bool flag;
            Card[] SevenCards = new Card[7];

            SevenCards[0].Color = CurrentPlayer.Card1.Color;
            SevenCards[0].Number = CurrentPlayer.Card1.Number;
            SevenCards[1].Color = CurrentPlayer.Color2;
            SevenCards[1].Number = CurrentPlayer.Number2;

            SevenCards[2] = Ground.Card1;
            SevenCards[3] = Ground.Card2;
            SevenCards[4] = Ground.Card3;
            SevenCards[5] = Ground.Card4;
            SevenCards[6] = Ground.Card5;

            flag = isThere_Pair(SevenCards); 

            return flag;
        }

以下是CurrentPlayer收到卡片的方式:

    public void Deal_Cards(Player Player)
    {
        int Color1, No1, Color2, No2;

        while (true)
        {


        dealhelper1:

            Color1 = (RandomColor.Next() % 4);
            No1 = ((RandomNo.Next() % 13));


            if (CardDeck[Color1, No1].isChosen == true)
            {
                goto dealhelper1;
            }

            if (CardDeck[Color1, No1].isChosen == false)
            {
                Player.Card1.Color = Color1;

                Player.Card1.Number = No1+1;
                Player.Card1.imagePath = CardDeck[Color1, No1].imagePath;

                Player.Color1 = CardDeck[Color1, No1].Color;
                Player.Number1 = CardDeck[Color1, No1].Number;                   

                CardDeck[Color1, No1].isChosen = true;
                break;
            }
        }

        while (true)
        {
            dealhelper2:

            Color2 = (RandomColor.Next() % 4);
            No2 = ((RandomNo.Next() % 13));

            if (CardDeck[Color2, No2].isChosen == true)
            {
                goto dealhelper2;
            }

            if (CardDeck[Color2, No2].isChosen == false)
            {
                CardDeck[Color2, No2].isChosen = true;


                Player.Card2.Color = Color2;
                Player.Card2.Number = (No2)+1;

                Player.Color2 = CardDeck[Color2, No2].Color;
                Player.Number2 = CardDeck[Color2, No2].Number;
                break;
            }
        }

        display_Player_Cards(Player);
    }

但是在hasPair函数中,CurrentPlayer的卡片的数字和颜色都是0.我尝试了不同的方式但是当我在查询中询问时,我无法获得播放器卡片的编号值,尽管它们已由Deal_Cards函数初始化。不过,地面卡没有问题。

有趣的是,display_Player_Cards(Player)函数正常工作(因此它成功获取值并显示卡片。)

我使用Player(struct)类型的公共变量,如:

    public Player P1 = new Player();
    public Player AI = new Player();

为什么他们不能坚守自己的价值观?我该如何解决这个问题? 谢谢你的帮助。

2 个答案:

答案 0 :(得分:6)

你遇到的问题是结构是通过.Net中的值传递的。因此,Deal_Cards方法会收到Player实例的副本,并将卡分配给该副本。传递给Deal_Cards的原始值未经修改。

要解决此问题,您需要将Player设为class或通过引用传递它。我强烈建议Player成为class。拥有可变结构只是一条痛苦的道路,很难找到像这样的错误。

答案 1 :(得分:0)

在C中,通过值传递struct有效地将结构的副本提供给被调用的例程;无论例程对其结构副本执行什么操作,调用者结构的字段都不会受到影响。如果希望被调用函数能够修改结构,则必须使其成为“ref”参数。

请注意,将结构作为ref参数传递比传递类对象引用具有更严格的语义。给出对类对象的引用的例程不仅可以对引用做任何想要的事情,而且可以使其可用于其他任何想要做任何事情的代码,只要它想要,甚至在最初给出引用的函数已返回。相比之下,给出struct作为ref参数的例程可以在返回之前对struct执行任何操作,但是在返回之后它将无法直接或间接地修改struct的字段。

您没有显示“播放器”数据类型的内容,因此不清楚它应该是结构还是类。然而,玩家的手似乎是结构的逻辑候选者,因为它只持有两张牌。让它成为一个可变的课程对我来说似乎真的很蠢。可以使玩家的手成为不可变的结构,并用Deal_Cards函数替换GenerateHand方法,该函数返回playerHand结构,或者将playerHand传递给{{} 1}}作为ref参数。如果一个人使用'immutable'路径,就可以使用一个类,但是我觉得在这个上下文中使用不可变类而不是不可变结构几乎没什么好处。