4

考虑以下 C#:

// C# .net
switch(x)
   {
    case 1:
        for(int i = 0; i < 10; i++)
        {
            int val = getValue(i);
            if (val == 0)
                goto endswitch;
        }
        doMoreStuff();
        break;
    case 2:
        doSomeThingElse();
        break;
    default: throw new ArgumentOutOfRangeException();
}
endswitch: ;

我编写了类似于上述代码示例的代码。问题是我需要从内部 for 循环中中断 switch 语句。如果我在break那里放一个语句,它只会破坏内部 for 循环然后继续执行doMoreStuff(),这不是我需要的。

似乎在这里效果最好的替代方法是goto声明,但我知道这是不赞成的。

另一种选择是在 for 循环中跟踪一个单独的变量,但这会增加代码行并且不太优雅。

做这个的最好方式是什么?

更新:我读到有一种方法可以在 JavaScript 中执行此操作。它的工作原理如下:(http://www.devguru.com/technologies/ecmascript/quickref/break.html)

// JavaScript
outer_loop:
for(i=0; i<3; i++)
{
   document.write("<BR>" + "outer " + i + ":   ");
   for(j=0; j<5; j++)
   {
      document.write("inner " + j + " ");
      if(j==x)
         break outer_loop;
   }
}

在 C# 中可能有这样的事情吗?

4

2 回答 2

7

您可以将检查抽象为带有返回标志的方法:

switch(x)
{
    case 1:
        if (ShouldDoMoreStuff())
            doMoreStuff();
        break;
    case 2:
        doSomeThingElse();
        break;
    default: throw new ArgumentOutOfRangeException();
}


private bool ShouldDoMoreStuff()
{
    for(int i = 0; i < 10; i++)
    {
        var val = getValue(i);
        if (val == 0)
            return false;
    }

    return true;
}

只是为了扩展,您可以像以前一样使用 goto,但它通常不受欢迎,尤其是在这种微不足道的情况下。 有时当你有很多很多嵌套循环或开关时它很有用,但这通常表明你应该重构/重新设计一下。正如您所指出的,您可以存储一个局部变量并进行检查,但正如您所意识到的那样,这有点迟钝/难闻。我更喜欢我在上面发布的这种方法,因为它变得非常易读。

编辑:关于您的评论和编辑的问题,我认为 C# 中不存在与您的 JavaScript 代码类似的语言功能。来自http://msdn.microsoft.com/en-us/library/37zc9d2w%28VS.80%29.aspx(强调添加):

在嵌套语句中,break 语句仅终止直接将其括起来的 do、for、switch 或 while 语句。您可以使用 return 或 goto 语句从更深的嵌套结构中转移控制。

于 2012-07-05T17:30:11.017 回答
0

这就是想太多导致的问题。如果在 for 循环之前满足您的条件,您可以简单地使用一个布尔值,并且仅在布尔值为真时运行您的方法,例如:

switch(x)
   {
    case 1:
        bool donrun;
        for(int i = 0; i < 10; i++)
        {
            int val = getValue(i);
            if (val == 0)
                donrun = true;
        }
        if(!donrun) doMoreStuff();
        break;
    case 2:
        doSomeThingElse();
        break;
    default: throw new ArgumentOutOfRangeException();
}
于 2012-07-05T19:00:50.217 回答