这个转到表达吗?

jsw*_*jsw 10 c# goto

以下代码是消息批处理例程的概念证明.我是否goto像瘟疫一样避免并重写此代码?或者您认为这goto是一种表达方式吗?

如果你重写,请发一些代码......

var queue = new Queue<TraceItem>(this.batch);
while (this.connected)
{
    byte[] buffer = null;
    try
    {
        socket.Recv(out buffer);
    }
    catch
    {
        // ignore the exception we get when the socket is shut down from another thread
        // the connected flag will be set to false and we'll break the loop
    }

HaveAnotherMessage:
    if (buffer != null)
    {
        try
        {
            var item = TraceItemSerializer.FromBytes(buffer);
            if (item != null)
            {
                queue.Enqueue(item);

                buffer = null;
                if (queue.Count < this.batch && socket.Recv(out buffer, ZMQ.NOBLOCK))
                {
                    goto HaveAnotherMessage;
                }
            }
        }
        catch (Exception ex)
        {
            this.ReceiverPerformanceCounter.IncrementDiagnosticExceptions();
            this.tracer.TraceException(TraceEventType.Error, 0, ex);
        }
    }

    // queue processing code
}
Run Code Online (Sandbox Code Playgroud)

Jos*_*h K 44

Goto会让你陷入困境

几乎总结了我对"goto"的看法.

由于很多原因,Goto编程很糟糕.其中最主要的是几乎没有理由.有人发布了一个do..while循环,使用它.使用a boolean检查是否应该继续.使用while循环.Goto用于解释语言和回调汇编日(JMP任何人?).出于某种原因,您使用的是高级语言.这样你和其他人就不会看你的代码而迷失方向.


为了使这个答案保持最新,我想指出,在iOS和OS X中,组合goto和支撑错误导致了一个主要的SSL错误.

  • 今天早些时候发生在我身上!我正在考虑写一个小的vs2010扩展,当你输入goto时会让计算机发出哔哔声. (2认同)
  • 实际上,GOTO语句确实有其优点,前提是它们仅在以下情况下使用:(1)替代解决方案可读性较差或不太直观;(2)易于遵循程序流程. (2认同)

cor*_*iKa 19

如果您不想使用现在的"始终运行一次"功能,请使用do-while或简单的while循环替换goto.

var queue = new Queue<TraceItem>(this.batch);
while (this.connected)
{
    byte[] buffer = null;
    try
    {
        socket.Recv(out buffer);
    }
    catch
    {
        // ignore the exception we get when the socket is shut down from another thread
        // the connected flag will be set to false and we'll break the loop
    }

    do {
        if (buffer != null)
        {
            try
            {
                var item = TraceItemSerializer.FromBytes(buffer);
                if (item != null)
                {
                    queue.Enqueue(item);
                    buffer = null;
                }
            }
            catch (Exception ex)
            {
                this.ReceiverPerformanceCounter.IncrementDiagnosticExceptions();
                this.tracer.TraceException(TraceEventType.Error, 0, ex);
            }
        }
    } while(queue.Count < this.batch && socket.Recv(out buffer, ZMQ.NOBLOCK))

    // queue processing code
}
Run Code Online (Sandbox Code Playgroud)

  • Imo,我更喜欢Josh的回答. (2认同)

Ran*_*pho 18

在这种情况下让你摆脱GOTO是非常容易的让它让我哭泣:

var queue = new Queue<TraceItem>(this.batch);
while (this.connected)
{
    byte[] buffer = null;
    try
    {
        socket.Recv(out buffer);
    }
    catch
    {
        // ignore the exception we get when the socket is shut down from another thread
        // the connected flag will be set to false and we'll break the loop
    }
    bool hasAnotherMessage = true
    while(hasAnotherMessage)
    {
        hasAnotherMessage = false;
        if (buffer != null)
        {
            try
            {
                var item = TraceItemSerializer.FromBytes(buffer);
                if (item != null)
                {
                    queue.Enqueue(item);

                    buffer = null;
                    if (queue.Count < this.batch && socket.Recv(out buffer, ZMQ.NOBLOCK))
                    {
                        hasAnotherMessage = true;
                    }
                }
            }
            catch (Exception ex)
            {
                this.ReceiverPerformanceCounter.IncrementDiagnosticExceptions();
                this.tracer.TraceException(TraceEventType.Error, 0, ex);
            }
        }
    }
    // queue processing code
}
Run Code Online (Sandbox Code Playgroud)

  • +1用于证明几乎所有的GOTO都只是远离死亡的一分钟. (2认同)

Pla*_*ure 5

我想goto在直觉上可读性更小...但是如果你想避免它我认为你所要做的就是将代码抛出一个while(true)循环,然后break在循环结束时有一个语句用于正常迭代.并且goto可以与被替换continue的语句.

最后,你学习读取和编写循环和其他控制流结构而不是使用goto语句,至少在我的经验中.