重新启动 Main() 的 C# 方法

C# Method that restarts Main()

我有一个 C# 方法,如果条件不满足我想重新 运行 Main() 方法。 有几篇文章说使用循环来做到这一点。 GoTo 也可以 - 但不要使用它。或者重新启动应用程序。

没有人对循环给出清晰的新手级别的解释。

C# 示例:

public static void Method3(int userChoice){
 if(userChoice == 1){
  Console.WriteLine("do this");
 }
 else{
  Main(); // How to run the main program again from the start ?
 }
}

public static void Main(string[] args)
{
 Method1();
 int userChoice = Method2();
 Method3(userChoice);  // I want Method3 to go back to Method1() if the else statement is met.
}      

在 python 中,这非常简单 - 您只需从函数中调用 Main()。

你可以让 Method3() return 一个 bool 这样 Main() 方法知道是否要重试。

public static bool Method3(int userChoice)
{
    if (userChoice == 1)
    {
        Console.WriteLine("do this");
        return false;
    }

    return true;
}

public static void Main(string[] args)
{
    bool tryAgain;
    do
    {
        Method1();
        int userChoice = Method2();
        tryAgain = Method3(userChoice);
    } while (tryAgain);       
}

简单地再次调用 Main() 而不是循环是另一种方法,但有一些缺点。

  • 您将不得不以某种方式提出 args 论点。也许在你的情况下它只是一个空数组。
  • 这是一个递归调用并影响堆栈跟踪。经过这么多次递归调用,你的应用程序会崩溃。
  • 它降低了可维护性。以后如果您想在 Main() 方法的顶部添加任何内容,您必须记住,您正在从某个地方调用它。它有助于引入潜在的难以诊断的错误。使用循环方法封装行为。只看 Main(),很明显 Method3() 可能会导致另一个循环。

所以这并不难,但你可以使用 while 循环。

C#:

public static void Main(string[] args)
{
     while(true)
     {
          Method1();
          int userChoice = Method2();
          Method3(userChoice);
     }
}

这会给你想要的东西,如果你想退出,你只需输入

break;

首先,是的,你可以调用Main。请注意,在您的示例中,您缺少 args 参数(将具有命令行参数)。除此之外,还要知道 Main returns,然后在你调用它的地方继续执行。此外,您很可能最终会出现堆栈溢出。 如果我没记错的话,JIT 的现代版本可以优化尾递归,但我不认为它们对这种特殊情况有效。


关于循环的新手级解释...这是一个无限循环,它将永远 运行:

while(true)
{
    // ...
}

您可以使用 break

退出循环
while(true)
{
    // ...
    if (something)
    {
        break;
    }
    // ...
}

或者您可以将 true 更改为有条件的:

while(!something)
{
    // ...
}

这个想法是将 Main 包裹在一个循环中,这样它将继续 运行 直到满足条件。您可以有另一个方法并在循环中调用它,例如:

public static bool Execute()
{
    if (something)
    {
        // do whatever
        return true;
    }
    return false;
}

public static void Main(string[] args)
{
    while (!Execute())
    {
        // Empty
    }
}

当然,除了 while loop, they are the do...while loop, for loop, and foreach loop 之外,还有其他类型的循环。


Goto 可以吗?可以说。这个想法是您可以使用 goto 来控制返回方法的执行流程。即:

label:
// ...
goto label;

上面的代码是一个死循环。当然可以引入条件:

label:
// ...
if (!something)
{
    goto label;
}
// ...

while 可以做——有时在变量的帮助下——任何你可以用 goto 做的事情,而且它通常更容易阅读,更不容易出错。


重启过程比较棘手,需要使用Process.Start to run your own executable. See What is the best way to get the executing exe's path in .NET?.