C# 保持检查值而不出现堆栈溢出

C# 保持检查值而不出现堆栈溢出,c#,stack-overflow,C#,Stack Overflow,对于我正在进行的一个小型C#Windows窗体项目,我需要问一个简单的Y/N问题。我需要它重复,直到给出正确的值。如果我使用此代码,它将创建堆栈溢出: void Intro() { if (input == "YES" || input == "Y") { //Do Stuff } else { Intro(); } } 我环顾

对于我正在进行的一个小型C#Windows窗体项目,我需要问一个简单的Y/N问题。我需要它重复,直到给出正确的值。如果我使用此代码,它将创建堆栈溢出:

    void Intro()
    {

        if (input == "YES" || input == "Y")
        {
          //Do Stuff
        }
        else
        { 
            Intro();
        }
    }
我环顾四周,显然最好的处理方法是使用while循环。因此,我尝试使用此代码,这导致在编译和运行时表单未加载:

    void Intro()
    {
        while (true)
        {
            if (input == "YES" || input == "Y")
            {
              //Do Stuff
            }
        }
    }

它不会给出任何错误,并一直运行直到我停止它。该方法在InitializeComponent之后立即运行。这可能是一个非常愚蠢的问题,如果能在几秒钟内得到回答,那么很抱歉。

在第一个问题中,您调用的是一种无休止的递归方法(一种调用自身的方法),它会导致堆栈溢出

然而,在第二个方法中,有一个方法被调用一次,并且在该方法中调用了一个循环

当循环进行下一次迭代时,上一次迭代将关闭,这不会导致堆栈溢出

哦,顺便说一句,你在循环中缺少了
break
keywork

void Intro()
{
    while (true)
    {
        if (input == "YES" || input == "Y")
        {
          //Do Stuff
          break;
        }
    }
}

在第一种方法中,您调用的是一种无止境的递归方法(一种调用自身的方法),这会导致堆栈溢出

然而,在第二个方法中,有一个方法被调用一次,并且在该方法中调用了一个循环

当循环进行下一次迭代时,上一次迭代将关闭,这不会导致堆栈溢出

哦,顺便说一句,你在循环中缺少了
break
keywork

void Intro()
{
    while (true)
    {
        if (input == "YES" || input == "Y")
        {
          //Do Stuff
          break;
        }
    }
}

你应该把支票放在一个事件中;它不一定是一个按钮点击事件

private void button_Click(object sender, EventArgs e)
{
     if(input=="YES" || input=="Y")
        //do stuff
     else
        //reshow question
}

你应该把支票放在一个事件中;它不一定是一个按钮点击事件

private void button_Click(object sender, EventArgs e)
{
     if(input=="YES" || input=="Y")
        //do stuff
     else
        //reshow question
}

第一个示例创建了堆栈溢出,因为输入!=Y、 所以它跳转到else分支,它再次调用intro,它再次调用intro,它再次调用intro,依此类推这是溢出的堆栈

如果在实例化表单时激活了第二个循环,那么它将永远无法从循环中实际显示表单


即使对于这样一个简单的表单,您也需要依赖事件来驱动逻辑。如果输入指的是文本框,则连接到
TextChanged
事件。表单不打算运行无休止的循环,因为除非它们在单独的线程中运行,否则它们将锁定UI,这会增加与UI交互的复杂性。

第一个示例创建堆栈溢出,因为输入!=Y、 所以它跳转到else分支,它再次调用intro,它再次调用intro,它再次调用intro,依此类推这是溢出的堆栈

如果在实例化表单时激活了第二个循环,那么它将永远无法从循环中实际显示表单


即使对于这样一个简单的表单,您也需要依赖事件来驱动逻辑。如果输入指的是文本框,则连接到
TextChanged
事件。表单不打算运行无休止的循环,因为它们将锁定UI,除非它们在单独的线程中运行,如果您需要与UI交互,这会导致额外的复杂性。

第一个代码创建了递归,太多的递归调用填满了堆栈,您会得到
堆栈溢出例外

第二个代码包含一个无限循环,该循环在没有任何延迟的情况下保持代码的执行,因此应用程序挂起

完成此任务的正确方法:

void Intro()
{
    while (true)
    {
        if (input == "YES" || input == "Y")
        {
          //Do Stuff
          break; //it will break the loop when you will get the correct value
        }
    }
}

另一方面,无论您是否获得正确的值,它都将继续执行代码。

第一个代码创建了递归,太多的递归调用填满了堆栈,您得到了
StackOverFlowException

第二个代码包含一个无限循环,该循环在没有任何延迟的情况下保持代码的执行,因此应用程序挂起

完成此任务的正确方法:

void Intro()
{
    while (true)
    {
        if (input == "YES" || input == "Y")
        {
          //Do Stuff
          break; //it will break the loop when you will get the correct value
        }
    }
}

另一方面,无论您是否获得正确的值,它都将继续执行代码。

第一个方法创建一个
堆栈
来存储上一次调用的地址,然后再调用下一个方法,此堆栈的大小有限,它将被您提供的代码溢出。第二个方法不需要任何堆栈,它只是一个循环,运行相同的代码段,而循环的条件仍然为true。第一个方法创建一个
堆栈
,以存储调用下一个方法之前最后一次调用的地址,此堆栈的大小有限,它将被您提供的代码溢出。第二个不需要任何堆栈,它只是一个循环,运行相同的代码段,而循环的条件仍然为真。嘿,OPs需要解释第一个代码和第二个代码之间的差异,第一个抛出
StackOverflowException
,而第二个没有,但是表单仍然没有出现。这个方法是在表单的构造函数中调用的吗?嘿,OPs需要解释第一个代码和第二个代码之间的区别,第一个抛出
StackOverflowException
,而第二个没有,但是表单仍然没有出现。这个方法是在表单的构造函数中调用的吗?