在交换机中使用'转到'?

Bre*_*ias 48 c# coding-style goto switch-statement

我已经看到了建议的编码标准Never use goto unless in a switch statement fall-through.

我不跟随.这个"例外"案件究竟是什么样的,这证明了一个goto

Meh*_*ari 93

这个结构在C#中是非法的:

switch (variable) {
   case 2: 
       Console.WriteLine("variable is >= 2");
   case 1:
       Console.WriteLine("variable is >= 1");
}
Run Code Online (Sandbox Code Playgroud)

在C++中,它会运行两行if variable = 2.这可能是故意的,但break;在第一个案例标签的末尾很难忘记.出于这个原因,他们在C#中将其定为非法.要模仿堕落行为,您必须明确goto表达您的意图:

switch (variable) {
   case 2: 
       Console.WriteLine("variable is >= 2");
       goto case 1;
   case 1:
       Console.WriteLine("variable is >= 1");
       break;
}
Run Code Online (Sandbox Code Playgroud)

也就是说,在某些情况下,goto这个问题实际上是一个很好的解决方案.绝不要以"从不使用某些东西"规则来关闭你的大脑.如果它是100%无用的,那么首先它不会存在于语言中.不要使用goto是一个指导方针 ; 这不是法律.

  • @Mehrdad:我很想读"永远不要关闭你的大脑",但我觉得我有点迟了..它似乎已经被删除了.如果您偶然有任何其他参考链接,是否可以刷新链接?谢谢 (2认同)
  • 这是不幸的,即使在最初的职位发布后5年仍然具有相关性 (2认同)
  • 你应该一直使用的唯一“最佳实践”是“用你的大脑”。太多的人追随太多的潮流,试图将方法、模式、框架等强加到不值得的事情上。仅仅因为某些东西是新的,或者因为受人尊敬的人有意见,并不意味着它适合所有人:) 编辑:只是为了澄清 - 我认为人们不应该忽视最佳实践、有价值的意见等。只是人们不应该只是盲目地跳上某件事,而不考虑为什么这个“东西”如此伟大,它是否适用于我正在做的事情,以及它带来什么好处/缺点? (2认同)

Zoo*_*oba 21

C#拒绝让案例隐含地通过(除非在案例中没有代码),就像在C++中一样:你需要包括break.要明确地通过(或跳转到任何其他情况),您可以使用goto case.由于没有其他方法可以获得此行为,因此大多数(合理的)编码标准都允许这样做.

switch(variable)
{
case 1:
case 2:
    // do something for 1 and 2
    goto case 3;
case 3:
case 4:
    // do something for 1, 2, 3 and 4
    break;
}
Run Code Online (Sandbox Code Playgroud)

一个现实的例子(按要求):

switch(typeOfPathName)
{
case "relative":
    pathName = Path.Combine(currentPath, pathName);
    goto case "absolute";

case "expand":
    pathName = Environment.ExpandEnvironmentVariables(pathName);
    goto case "absolute";

case "absolute":
    using (var file = new FileStream(pathName))
    { ... }
    break;

case "registry":
    ...
    break;
}
Run Code Online (Sandbox Code Playgroud)

  • "这种例外情况"指的是"在一个转换语句中,",使用"除非"一词表示在主题之前指定的"从不使用"的一般规则的例外,"转到".(如果我走得太快,请阻止我.) (2认同)

dje*_*eeg 7

   public enum ExitAction {
        Cancel,
        LogAndExit,
        Exit
    }
Run Code Online (Sandbox Code Playgroud)

这个更整洁

ExitAction action = ExitAction.LogAndExit;
switch (action) {
    case ExitAction.Cancel:
        break;
    case ExitAction.LogAndExit:
        Log("Exiting");
        goto case ExitAction.Exit;
    case ExitAction.Exit:
        Quit();
        break;
}
Run Code Online (Sandbox Code Playgroud)

比这更好(特别是如果你在Quit()中做更多的工作)

ExitAction action = ExitAction.LogAndExit;
switch (action) {
    case ExitAction.Cancel:
        break;
    case ExitAction.LogAndExit:
        Log("Exiting");
        Quit();
        break;
    case ExitAction.Exit:
        Quit();
        break;
}
Run Code Online (Sandbox Code Playgroud)

  • 错误,是的,你可以,枚举被视为常量 (6认同)
  • Gah,我早先测试时一定是错误的.它现在编译...我发誓以前没有.抱歉.+1 (2认同)

小智 5

除了使用之外goto case,您还可以goto在另一个case子句中使用标签:

    switch(i) {
    case "0":
        // do some stuff
        break;
    case "1":
        // other stuff, then "fall through" to next case clause
        goto Case2;
    case "2":
    Case2:
        break;
    }
Run Code Online (Sandbox Code Playgroud)

这样,您可以跳转到另一个case子句,而不必担心表达式的值或类型。

某种可以替代的显式“ fallthrough”关键字break会很不错,尽管...

  • 它可能是死灵术,但这是一种很好的死灵术。它实际上帮助了我。:) +1 (2认同)