最佳实践:从switch语句的case块中返回方法?

时间:2010-08-27 21:15:40

标签: c# .net

哪种从switch语句返回bool的方法更可取?我知道这可能是主观的,但是我认为对我们的专业来说,获得最佳实践的意见很重要:)。

public bool foo(param)
{
    switch (param)
    {
        case 1:
            if (something)
            {
                return true;
            }

            return false;    
        default:
            return false;
     }
}

- 或 -

public bool foo(param)
{
    bool flag = false;

    switch (param)
    {
        case 1:
            if (something)
            {
                flag = true;
            }
            break;
        default:
            break;
     }

    return flag;
}

8 个答案:

答案 0 :(得分:14)

这里的区别在于单点回报和多点回报。

通常,单点返回代码往往会执行大量的簿记(临时变量,在循环中检查这些变量),并且随着逻辑变得更复杂而变得毛茸茸。我已经看到了使用while (flag) ... flag = false;模式而不是while (true) ... break;模式的代码,并且读取它并不好玩。

我更喜欢多个返回点,因为它们尽早返回(没有额外的工作完成)并且不需要任何本地人来帮助跟踪当前的返回值。另外,我发现它们比单点返回代码更难阅读。

在c2(SingleFunctionExitPoint)上有一个很好的讨论。

我发现将方法保持为“功能”是一件好事(我说这里的“功能”因为我通常做的是C#,在LINQ之外,它不被认为是功能性的)。通过“功能”,我的意思是我尽量避免变异状态。以本地或成员的形式引入更多状态会使事情变得更难以理解,因为您现在必须考虑它们的值,并且您必须考虑如何设置这些变量(来自另一个方法,来自另一个类,......)

一般来说,国家是邪恶的,但有时它是必要的邪恶。

此特定问题也有一些有趣的对话here on SO

答案 1 :(得分:6)

我更喜欢第二种方法 它更具适应性,你可以在函数末尾添加一些工作,这取决于flag

另外,如果你只有一个案例,你可能想要转移到开关以外的东西

答案 2 :(得分:3)

我更喜欢早期回归 - 但总的来说,我真的尽量避免切换,除非它在最多3个选项之间进行选择。我尝试尽可能地隔离开关,这样带开关的方法只能确定变量部分 - 其他一切都由调用代码处理。

IMO,早期回归更容易阅读,因为当我遇到回报时我不需要“进一步”阅读。

答案 3 :(得分:2)

这看起来像真的复杂的策略,以避免&&运营商。布尔表达式是coolio:

public bool foo(int param)
{
    return (param == 1) && something;
}

答案 4 :(得分:2)

鉴于这两个选项,我说两者都不是因为它们嵌套得太远 - 你应该调用一个在你的例子中返回一个布尔值的函数。

考虑到单点返回和多点返回之间的问题(以及我之前的观点),我采用多点返回,因为你可以返回你返回的函数的值。

举个例子:

public bool foo(param)
{
    switch (param)
    {
        case 1:
            return MethodForParamEqualOne();
        default:
            throw new ArgumentException("Param value=" + param + " is not supported.");
    }
    //If you're doing stuff here, the method is likely doing too much.
}

最终这些switch语句被重构为对象的方法调用(这将改善可怕的嵌套开关给你)。如果你真的很精明,你甚至可能不需要在对象工厂中使用switch语句(xml configs,reflection,database,...)。

答案 5 :(得分:1)

这完全取决于我在做什么。如果我这样做然后我就完了,我会回来 - 为什么要执行不必要的代码?如果我想做更多工作,那么我会设置一个标志或其他东西。使用正确的工具来完成正确的工作。

答案 6 :(得分:1)

我会完全删除switch语句:

public bool foo(param)
{
   if(param != 1)
   {
    throw new ArgumentException("Param value=" + param + " is not supported.");
   }

   return MethodForParamEqualOne();
}

答案 7 :(得分:1)

当涉及到条件块的返回和选择时,始终保持在脑后,对注释关键代码进行评论可能是个好主意。如果你使用

  

而(真)

不要害怕扔掉

  

//警告+原因!

在中断代码之上。通常大多数人都会告诉你,这种情况有点过分了,但是一旦它变得更加愚蠢

for (int x = 0; /*external variable for condition*/ ; x ++)

我发现在快速尝试测试很多代码中的小变化时,我经常发现这有助于我防止代码破坏,你实际上不需要再阅读那么多代码来为其他人提供小额奖励。

说实话,有点花生,但我只是觉得我会分享对我有帮助的东西,所以它可以帮助别人。

bool a = false;

while(true)
{
   ReDraw();
   ReUpdate();       

   //WARNING! Critical breakpoint   <--- Edit , nobody likes a game you can't win :P
   a = CheckForWinGame();
   if (a) 
   { 
      break; 
   }
}

在这个例子中,我希望能够在眨眼间告诉我这个警告,我可以干涉方法,但不能用最后一个方法。它不防水,但它很快