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
的实际用例。
我是 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
的实际用例。