2016-08-16 125 views
2

我对C#很有新意(一周前开始学习它),在批处理和表达式2方面有一些经验,并且我一直在尝试基于文本的游戏,学到更多。起初我使用了goto语句,但根据我发现的几乎所有人,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做出的示例根本不适用于我,因此可能不值得尝试使这个特定的例子有效。

+1

我认为这个问题是一个更合适的网站是一个网站http://codereview.stackexchange.com/ – BWA

+1

是啊,不要使用goto语句,永远 – Liam

+0

@Liam该帖子的全部内容是不使用goto声明,永远。 –

回答

0

您可以使用递归返回并再次执行代码。为此,你可以在你的代码移到一个单独的方法,并从它里面调用它时,它是必要的:

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 number is successfully parsed return number else run method again 
     return int.TryParse(Console.ReadLine(), out num)? 
        num : EnterNumber(); 
    } 

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

当我们可以使用的方法,循环和递归没有实际上需要使用GO TO了。

-1

通常您使用方法或lambda表达式。因此,您的mainmenu将成为您在代码结尾再次调用的方法。

3

至于我可以看到你想要的无限循环

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

     Go = 0; 

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

几分钟前,我评论了这一点,并说它行得通,而且它也适用于这个例子,但我忽略了提及将会有多种选择;不只是一家商店。如果我像这样使用了一个无限循环,我想我必须遍历每个菜单,除非可能使用了很多循环。 –

+0

@Rowan Tarshis:为什么不添加另一个菜单项,*退出*,只是调用'break;'(只留下无限循环)或'return;'(离开Main函数,因此程序)? –

+0

我不确定你的意思。通过“另一个菜单项”,你是指另一个菜单,如商店,还是别的?此外,通过“刚才调用break的exit”(上面只留下无限循环),“你的意思是它会'break',进入第二个无限循环,还是我误解了这一点? –

0

一个建议是使用一个开关的情况下构建这样的:

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(); 

}