【问题标题】:How can I pass data to a method in a different class?如何将数据传递给不同类中的方法?
【发布时间】:2020-03-10 05:31:18
【问题描述】:

在编程方面我还是个菜鸟,我决定要测试我的极限并创建一个井字游戏。我确信有更好的方法来做我想做的事情,但我只是还在学习。在测试我到目前为止的内容时,我遇到了这个问题,要求用户输入一个位置(位置是 1-9,这些位置最终将用于告诉程序将用户 X 放在哪里或 O)。我现在有 2 个课程,主要课程和董事会课程。通过放置停止标记进行一些调试后,我开始意识到,当我从主类中的板类调用方法时,放入该方法的参数中的数据并没有传递.

主类:

class Program {
        static void Main(string[] args) {
            Board board = new Board();

            bool hasWon = false;

            string p1;
            string p2;
            string pos;
            int turn = 2;

            Console.Write("Please enter a name for player 1: ");
            p1 = Console.ReadLine();
            Console.Clear();
            Console.Write("Please enter a name for player 2: ");
            p2 = Console.ReadLine();
            Console.Clear();

            while (hasWon == false) {
                if (turn % 2 == 0) {
                    Console.WriteLine(p1 + "'s Turn / You are X's");
                    board.DisplayBoard();
                    Console.WriteLine();
                    Console.WriteLine("Please selecet a position: ");
                    board.SetPos(Console.ReadLine());

                    Console.WriteLine("Position correctly set: " + board.GetPos());
                } else {
                    Console.WriteLine(p2 + "'s Turn / You are O's");
                    board.DisplayBoard();
                    Console.WriteLine();
                    Console.WriteLine("Please selecet a position: ");
                    board.SetPos(Console.ReadLine());

                    Console.WriteLine("Position correctly set: " + board.GetPos());
                }
            }
        }
    }

板级:

public class Board {

        private string pos = "";
        private string badPos = "";
        public void DisplayBoard() {
            Console.WriteLine(" 1 | 2 | 3 ");
            Console.WriteLine("-----------");
            Console.WriteLine(" 4 | 5 | 6");
            Console.WriteLine("-----------");
            Console.WriteLine(" 7 | 8 | 9 ");
        }

        public void SetPos(string pos) {
            if (this.pos.Length > 1 || this.pos.Length < 1) {
                this.pos = badPos;
                IncorrectPosition();
            } else if (!this.pos.Contains("1") || this.pos.Contains("2") || this.pos.Contains("3") || this.pos.Contains("4") ||
                this.pos.Contains("5") || this.pos.Contains("6") || this.pos.Contains("7") || this.pos.Contains("8") ||
                this.pos.Contains("9")) {
                this.pos = badPos;
                IncorrectPosition();
            } else {
                this.pos = pos;
            }
        }

        public string GetPos() {
            return pos;
        }

        /*public void setTurn(int turn) {
            turn = this.turn;
        }*/

        private void IncorrectPosition() {
            Console.Clear();
            Console.WriteLine(badPos + " is not a correct position");
            Console.Write("Please enter a position: ");
            SetPos(Console.ReadLine());
        }

    }

更具体地说,问题发生在 Main 类中。当用户被要求输入位置时,他们通过输入数字 1-9 来完成。在 Board 类中,有一个名为 SetPos 的方法,稍后我开发该方法时将使用该方法确定 X 或 O 的放置位置。但是,我还有一种方法可以确保用户输入的是数字 1-9。我不想将其转换为整数,我希望它保持为字符串。每当用户为该职位输入任何内容时,都不会保留任何内容。当使用停止标记并逐步完成程序时,在观察列表中我可以看到哪些值被分配给哪些变量,我的 pos 变量确实被分配给我输入的内容,但随后丢失因此重复SetPos 和 IncorrectPosition。当 IncorrectPosition 显示到控制台时,它会显示

位置不正确
请输入职位:

在 SetPos() 方法中,我尝试了一些方法来解决这个问题,其中之一是我添加了一个 badPos 变量,这意味着如果我的 if 语句中的前两件事中的任何一个为真,那么值通过我的 Main 类中的 SetPos() 方法传递的值将被分配给 badPos,但是当打印到控制台时,屏幕上没有显示任何值,这是另一种告诉方式我从来没有分配过任何价值。

我不知道如何解决这个问题,任何帮助将不胜感激,谢谢!

【问题讨论】:

  • if (this.pos.Length &gt; 1 || this.pos.Length &lt; 1) 您正在检查this.pos(类字段),而您应该检查pos(函数参数)。 (对于初学者。当然还有很大的改进空间。但这是主要的故障。)
  • 顺便说一句:你永远不会改变 turnhasWon。所以你的玩家 1 将永远玩下去......但我想,你打算在修复上述错误后这样做,对吧?到目前为止,您的整个 Board 课程没有多大意义。
  • @Fildor 只是为了让我能更好地理解,为什么检查 this.pos.Length 不起作用?在检查用户传递的位置值并确保它确实是正确的位置之前,不会为 board 类中的 pos 变量分配值。如果我改为检查 pos 变量,而不是 this.pos,它不会仍然显示它是空的吗? (再一次,这只是为了让我可以进一步理解为什么会这样。)是的,我还没有实施任何获胜或切换回合的方法。在继续之前,我主要想解决这个问题。
  • 好吧,你有点回答了你自己的问题:“在检查用户传递的位置值之前,不会为 board 类中的 pos 变量赋值”只是您检查传递的位置值。您检查板类的位置字段,正如您所知,尚未设置。而且,永远不会。 this.pos 是 board 类的 pos 字段,而不是方法参数。您可以通过将参数重命名为其他内容来轻松检查这一点。这样就不会那么混乱了。
  • 顺便说一句:我刚刚看到您递归处理无效条目。在这种情况下,我认为这不是一个特别糟糕的问题。但是您应该考虑改用循环。如果您在没有用户交互的设置中使用这样的构造并且递归深度越来越增加,您可能会最终导致堆栈溢出。

标签: c# methods arguments parameter-passing


【解决方案1】:
public void SetPos(string pos) 
{
    if (this.pos.Length > 1 || this.pos.Length < 1) 
    {   
        // by using "this" you are checking "pos" in the class and not the provided value
        // I'll assume that that "badPos" here is a placeholder as this would result in this.pos getting set to null because a variable named badPos has yet to be declared in this scope
        this.pos = badPos; 
        IncorrectPosition();
    } 
    else if (!this.pos.Contains("1") || this.pos.Contains("2") 
        || this.pos.Contains("3") || this.pos.Contains("4") 
        || this.pos.Contains("5") || this.pos.Contains("6") 
        || this.pos.Contains("7") || this.pos.Contains("8") 
        || this.pos.Contains("9")) 
    {
            // why not just use an int here? also if I'm reading this correctly 2 through 9 will make this true and then tell the player that this is a bad position. 
            this.pos = badPos;
            IncorrectPosition();
    } 
    else 
    {
        this.pos = pos;
    }
}

我会这样做:

public void SetPos(int pos) 
{
    if (pos > 0 && pos < 10)
    {
        // when you devise a way to store the board state you would check if the position is occupied here and any other checks you want to do - before assigning the value
        this.pos=pos;
    }
    else
    {
        this.pos = null;
        IncorrectPosition();
    }
}

所以,我使用了一个 int,而你说你不想使用它——我想你会发现,当你尝试构建一个数据结构来保存你的棋盘状态时——数学将是不可避免的。对于您使用,字符串“1”和 int 1 之间没有区别,只是一个比另一个更难验证

我离题了

您的检查总是出现“错误位置”的原因是,在您的第一个 if 子句中,您使用 'this' 检查 pos.lengthclass 的 副本是大于还是小于 1 -因为它在检查时为空,所以它的长度为 0,因此该子句返回 true。

你需要通过 pos 来引用传递的变量,而不是前面的 this

【讨论】:

    猜你喜欢
    • 2014-03-24
    • 1970-01-01
    • 2022-01-10
    • 2011-03-27
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多