C#goto使用 - 这里还有什么用?

时间:2010-09-24 09:03:07

标签: c# syntax goto

我知道使用goto是大多数人都要避免的事情,但是我已经阅读过各种各样的地方,如果你需要简单的代码,有时它会很有用。 目前我有一个非常简单的程序,如果用户选择这样,需要重复:

static void Main()
{
    Restart:
    ...

    string UserChoice=Console.ReadLine();
    if (UserChoice=="y")
    goto Restart;
}

在这里使用goto真的很糟糕吗?我只是看不到任何其他方式如何重复代码而不做循环等。这似乎是非常简单和干净的方式。或者我错过了什么?

11 个答案:

答案 0 :(得分:20)

string userchoice;

do {                

    userchoice=Console.ReadLine();

} while (userchoice=="y");

答案 1 :(得分:5)

而是写下面的内容。

while(Console.ReadLine() == "y")
{
.....
}

是的,使用goto很糟糕,因为它会降低你的代码的可读性。

答案 2 :(得分:5)

当然,如果你的代码要反复做同样的事情,你必须添加一个循环。这比goto要好得多。

使用类似的东西

string UserChoice = "y";
while( UserChoice == "y"){
  ...
  UserChoice=Console.ReadLine();
}

这应该对你有用。

答案 3 :(得分:4)

  

在这里使用goto真的很糟糕吗?

1968年3月,Dijkstra发送了一封信给Communications of the ACM,该信件以Go To Statement Considered Harmful标题发布。这是一本有趣的读物,也是程序员传说的一部分。

这封信中提出的反对GOTO的论点与程序员如何建立一个心智模型以跟踪代码执行的进度有关。 Dijkstra认为这样的心理模型很重要,因为变量的值仅相对于执行进度有意义。例如,当我们的程序计算事件发生的次数时,总是存在N个事件发生的中间时刻,但是跟踪它的变量尚未增加并且仍然是N-1。

他在反对GOTO的推理中经历了这些步骤:

  1. 首先考虑一种非常简单的语言,没有程序,循环或GOTO。在这种语言中,程序员可以通过想象从文件开始前进到结束的执行指针来在心理上跟踪执行。单个索引(即行号)足以模拟执行进度。

  2. 现在我们为该语言添加程序。单个索引无法再跟踪执行进度,因为它可能位于过程内。我们还必须跟踪调用过程的哪一行。此外,可以从其他过程调用过程。因此,我们将执行进度建模为一系列索引。 (在现实生活中,程序员将这样的序列称为“堆栈跟踪”。)

  3. 现在我们为语言添加循环。对于循环体内的堆栈跟踪中的每一行,我们需要为模型执行进度添加另一种类型的索引:重复计数。

  4. 现在我们添加GOTO。 Dijkstra认为,通过肆无忌惮地使用GOTO,我们跟踪执行进度的能力现在已经破裂。我们仍然可以通过说“现在我们正在执行第152条语句”来跟踪“执行时钟”的执行进度。但是,这对于建立解释变量值所必需的上下文并没有多大帮助。

  5. 只要我们只使用GOTO语句来构建简单的循环,你就可以说这种情况等同于第(3)点,并且没有问题。但在这种情况下,您可以使用循环结构。最好只保留GOTO代码,这样就不会陷入第(4)点所述的情况。

答案 4 :(得分:3)

我使用do / while循环:

string UserChoice = "";
do {
    ...
    UserChoice=Console.ReadLine();
} while(UserChoice == "y");

答案 5 :(得分:2)

您可以使用递归函数在没有循环的情况下执行相同的操作:

public static void Main(string[] args)
{
   PrintChoices();
}

private static void PrintChoices()
{
    string userChoice = Console.ReadLine();

    if (userChoice == "y")
        PrintChoices();        
}

答案 6 :(得分:2)

更广泛地接受使用方法而不是GOTO:

static void Main()
{
    Restart();
}

static void Restart()
{
    ...code

    string userChoice = Console.ReadLine();
    if (userChoice=="y")
        Restart();
}

答案 7 :(得分:2)

答案中缺少一个基本解决方案,

while (true)
{
    ...
    if (other-stop-condition) break;     

    ...

    string UserChoice=Console.ReadLine();
    if (UserChoice != "y") break;
}

break语句被认为不是纯粹的结构,而是结构比(真实的)goto更结构化。它应该谨慎使用,但它的用途与other-stop-condition

一样
  

在这里使用goto真的很糟糕?

不在这个简单的程序中。但是,如果您继续使用goto替换循环,if / then等等,您的代码的复杂性将比避免goto的代码快得多。

答案 8 :(得分:1)

使用do while循环将goto替换为更具可读性。

do 
{
...
}
while(Console.ReadLine() == "y");

答案 9 :(得分:0)

我个人从来没有使用过goto,就像ØyvindBråthen和Numenor所说的那样,循环方法是迄今为止完成这项任务的最佳方法。

但是,有一种情况我可以想到goto会有用的地方

因为交换机“掉头”在C#中是非法的(导致编译器错误):

switch (a) 
{ 
    case 3: 
        b = 7; 
    case 4: 
        c = 3; 
        break; 
    default: 
        b = 2; 
        c = 4; 
        break; 
}

要使其正常工作,您可以使用转到:

switch (a) 
{ 
    case 3: 
        b = 7;
        goto case 4;
    case 4: 
        c = 3; 
        break; 
    default: 
        b = 2; 
        c = 4; 
        break; 
}

答案 10 :(得分:0)

class Program
{
    static void Main(string[] args)
    {
        int add;
        try
        {
            ArrayList al = new ArrayList();
        t:
            Console.Write("Enter the Number of elements do you want to insert in arraylist");
            int n = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("Enter the Values:");
            for (int i = 0; i < n; i++)
            {
                al.Add(Console.ReadLine());

            }
            foreach (var a in al)
            {
                Console.WriteLine("valus:" + a);
            }
            Console.WriteLine("Add another number yes:1 ");
            add = Convert.ToInt32(Console.ReadLine());
            while (add == 1)
            {
                goto t;

            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Enter the Valid Number and try again");
        }
        Console.ReadKey();


    }
}

}