goto 语句的替代方法

Alternative to goto statement

我是 C# 的新手(一周前开始学习),在批处理和表达式 2 方面有一点经验,并且我一直在开发基于文本的游戏以尝试了解更多信息.起初我使用 goto 语句,但根据我发现的几乎每个人的说法,goto 语句是死亡和绝望的混合体,所以我想学习更干净、不那么邪恶的方法来达到同样的效果。这是我为了证明我的意思而制作的一个糟糕的示例脚本:

using System;

namespace TestScript
{
class Program
{
   public static void Main(string[] args)
    {
       string ConsoleReadinator;
        string ConsoleReadinator2;
        int Go = 0;

    mainmenu:
        do
        {
            Go = 0;
            Console.Clear();
            Console.WriteLine("Main Menu:");
            Console.WriteLine("Store or something");
            ConsoleReadinator = Console.ReadLine().ToUpper();
            if (ConsoleReadinator == "STORE") { Go = 1; }
        } while (Go == 0);

      // In-game store example

        {
            Go = 0;
            do
            {
                Console.Clear();
                Console.WriteLine("In-game store I guess");
                Console.WriteLine("Stuff you can buy, etc");
                ConsoleReadinator2 = Console.ReadLine().ToUpper();
                if (ConsoleReadinator2 == "GO") { Go = 1; }
            } while (Go == 0);
            goto mainmenu;
        }
    }
  }
}

这个脚本是有效的,但我想避免使用 goto 作为返回到先前语句的方式,以便导航菜单并可能重复回合制游戏的算法。我在 Alternative to using goto statement in C# 中读到了关于为此使用方法的信息(这基本上是我遇到的相同问题,只是有点模糊),但是 Greg 在那里做的例子对我来说根本不起作用,以至于它是可能不值得尝试使该特定示例起作用。

通常您使用方法或 lambda 表达式。所以你的主菜单将成为你在代码末尾再次调用的方法。

据我所知你想要一个无限循环:

  ...
  while (true) 
  {
      do
      {
         ...
      } while (Go == 0);

      Go = 0;

      do
      {
         ...
      } while (Go == 0);
  }

一个建议是使用这样的 switch case 结构:

static void Main(string[] args)
{
    string ConsoleReadinator;
    string MENU_TEXT = "Main Menu:";
    string ADDITIONAL_INFO = "Store or something";

    bool endProg = false;


    ConsoleReadinator = printMenu(MENU_TEXT, ADDITIONAL_INFO);

    // as long "EXIT" is not typed
    while (!endProg)
    {

        switch (ConsoleReadinator)
        {
            case "STORE":
                // Do your Store Stuff
                // maybe change MENU_TEXT and ADDITIONAL_INFO 
                // and print a new Menu
                ConsoleReadinator = printMenu(MENU_TEXT, ADDITIONAL_INFO);
                break;
            case "GO":
                // Do your Go Stuff
                break;
            case "EXIT":
                endProg = true;   // set exit condition to true
                break;

            default:                        
                break;
        }
    }

    Console.ReadKey();
}

// one Method to use for Menu display
public static string printMenu(string menuText, string additionalInfo)
{
    Console.Clear();
    Console.WriteLine(menuText);
    Console.WriteLine(additionalInfo);

    return Console.ReadLine().ToUpper();

}

您可以使用递归返回并再次执行代码。为此,您可以将代码移至单独的方法并在此方法中调用它:

class Program
{
   public static void Main(string[] args)
   {
        string ConsoleReadinator;
        string ConsoleReadinator2;
        Method(0);
   }
 
   private static void Method(int Go)
   {    
        do
        {
            ..
        } while (Go == 0);

      // In-game store example

        do
        {
           ...
        } while (Go == 0);
        Method(Go);
   }
}

或者您可以更好地使用循环。让我们看一下我们希望用户输入整数的示例:

   public static void Main(string[] args)
   {
       int num;

       // This loop ends only when user enters proper integer number
       do
       {
          Console.Clear();
          Console.Write("Please enter some integer number: ");
       } while(!int.TryParse(Console.ReadLine(), out num));                      
   }

这可以通过递归的其他方式完成:

   public static int EnterNumber()
   {
       Console.Clear();
       Console.Write("Please enter some integer number: ");

       // if the number is successfully parsed return number else run this method again
       return int.TryParse(Console.ReadLine(), out num) ? num : EnterNumber();
   }

   public static void Main(string[] args)
   {
       int num = EnterNumber();
   }

有了我们拥有的所有选项(方法、循环和递归),不再有使用 GO TO 的实际用例。