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

发布于 2024-09-24 17:59:24 字数 322 浏览 0 评论 0原文

我知道大多数人都说要避免使用 goto,但是我在很多地方读到,如果您需要简单的代码,有时它很有用。 目前我有非常简单的程序,如果用户选择这样,则需要重复:

static void Main()
{
    Restart:
    ...

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

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

I know using goto is something most people say to avoid, however I have read on various places that sometimes it is useful if you need simple code.
Currently I have very simple program that needs to be repeated if user selects so:

static void Main()
{
    Restart:
    ...

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

Is using goto here really so bad? I just cannot see any other way how to repeat the code without doing loops etc. This seems to be very straightforward and clean way. Or am I missing something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

筱武穆 2024-10-01 17:59:24
string userchoice;

do {                

    userchoice=Console.ReadLine();

} while (userchoice=="y");
string userchoice;

do {                

    userchoice=Console.ReadLine();

} while (userchoice=="y");
娇俏 2024-10-01 17:59:24

而是写如下所示的内容。

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

是的,使用 goto 是不好的,因为它会降低代码的可读性。

instead write something like below.

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

Yes using goto is bad because it makes your code less readable.

魂牵梦绕锁你心扉 2024-10-01 17:59:24

当然,如果您的代码要一次又一次地执行相同的操作,则必须添加循环。这比 goto 好多了。

使用类似这样的东西

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

应该对你有用。

Of course if your code is going to do the same thing again and again, you have to add a loop. That's much better than goto.

Use something like this

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

That should work out well for you.

固执像三岁 2024-10-01 17:59:24

这里使用 goto 真的那么糟糕吗?

1968 年 3 月,DijkstraACM 通讯,其标题为 转到被认为有害的声明。这是一本有趣的读物,也是程序员知识的一部分。

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

他在反对 GOTO 的推理中经历了以下步骤:

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

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

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

  4. 现在我们添加GOTO。 Dijkstra 认为,由于无节制地使用 GOTO,我们跟踪执行进度的能力现在崩溃了。我们仍然可以通过“执行时钟”来跟踪执行进度,方法是“现在我们正在执行第 152 条语句”。但是,这对于建立解释变量值所需的上下文并没有真正的帮助。

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

Is using goto here really so bad?

In March 1968, Dijkstra sent a letter to Communications of the ACM which was published under the title Go To Statement Considered Harmful. It is an interesting read, and part of programmer lore.

The argument against GOTO presented in this letter has to do with how programmers build a mental model to track the progress of code execution. Dijkstra argues that such a mental model is important, because the value of variables is meaningful only relative to the execution progress. For example, when our program is counting the number of times an event occurs, there is always an in-between moment where N events have occurred, but the variable keeping track of it has not yet been incremented and is still at N-1.

He goes through these steps in his reasoning against GOTO:

  1. First consider a very simple language without procedures, loops or GOTO. In such a language, the programmer can mentally track execution by imagining an execution pointer advancing from the start of the file to the end. A single index (i.e. the line number) suffices to model execution progress.

  2. Now we add procedures to the language. The execution progress can no longer be tracked by a single index, as it might be inside a procedure. We also have to keep track from which line the procedure was called. Also, procedures can be called from other procedures. Therefore, we model execution progress as a sequence of indices. (In real life, programmers call such a sequence a "stack trace".)

  3. Now we add loops to the language. For each line in our stack trace that is inside a loop body, we need to add another type of index to model execution progress: the repetition count.

  4. Now we add GOTO. Dijkstra argues that with unbridled use of GOTO, our ability to track execution progress now breaks down. We can still track execution progress with an "execution clock" by saying "now we're executing the 152nd statement". However, this is not really helpful to establish the context that is necessary to interpret the values of variables.

As long as we only use GOTO statements to build simple loops, you can argue that the situation is equivalent to point (3), and there is no problem. But in that case you can just use the loop constructs. Better to just keep GOTO out of your code, so that you don't slip into the situation described in point (4).

冷月断魂刀 2024-10-01 17:59:24

我会使用 do/while 循环:

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

I'd use a do/while loop:

string UserChoice = "";
do {
    ...
    UserChoice=Console.ReadLine();
} while(UserChoice == "y");
在梵高的星空下 2024-10-01 17:59:24

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

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

    ...

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

break 语句被认为不如纯 while 结构化,但比(真正的)goto 结构化。应谨慎使用它,但它有其用途,就像与 other-stop-condition 一样

这里使用goto真的那么糟糕吗?

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

There is one basic solution missing in the answers,

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

    ...

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

The break statement is considered to be less structured than a pure while but more structured than a (real) goto. It should be used sparingly, but it has its uses like with the other-stop-condition

is using goto here really so bad?

Not in this simple program. But if you continue to use goto to replace loops, if/then etc your code will increase in complexity much faster than code that avoids goto.

凡间太子 2024-10-01 17:59:24

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

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

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

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

You could use a recursive function to do the same without loops:

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

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

    if (userChoice == "y")
        PrintChoices();        
}
っ左 2024-10-01 17:59:24

使用方法代替 GOTO 被更广泛地接受:

static void Main()
{
    Restart();
}

static void Restart()
{
    ...code

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

Using methods instead of GOTOs is more widely accepted:

static void Main()
{
    Restart();
}

static void Restart()
{
    ...code

    string userChoice = Console.ReadLine();
    if (userChoice=="y")
        Restart();
}
や莫失莫忘 2024-10-01 17:59:24

使用 do while 循环来替换 goto,因为它更具可读性。

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

Use a do while loop to replace your goto as its much more readable.

do 
{
...
}
while(Console.ReadLine() == "y");
你的笑 2024-10-01 17:59:24

就我个人而言,我从来没有使用过 goto,并且像 Øyvind Bråthen 和 Numenor 一样,循环方法是迄今为止完成此任务的最佳方法。

然而,在一种情况下,我可以想到 goto 会有所帮助

,因为切换“失败”在 C# 中是非法的(导致编译器错误):

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

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

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

Personally I have never had to use a goto, and like Øyvind Bråthen and Numenor have stated the loop method is by far the best way of doing this task.

However, there is one case that I can think of where a goto would be helpful

As a switch “fall through” is illegal in C# (causes a compiler error):

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

To get it to work you can use a goto:

switch (a) 
{ 
    case 3: 
        b = 7;
        goto case 4;
    case 4: 
        c = 3; 
        break; 
    default: 
        b = 2; 
        c = 4; 
        break; 
}
末骤雨初歇 2024-10-01 17:59:24
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();


    }
}

}

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


    }
}

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文