在属性中使用开关检索值时,我应该使用变量作为switch语句还是return语句?

时间:2012-09-20 20:22:30

标签: c# coding-style switch-statement

我应该在返回之前保存switch语句的结果吗?或者,当我得到它时,我应该在开关中返回值吗?是否有一种方式比另一种更好的风格?

使用临时变量:

      public double xMax {
      get {
           double val = 0.00f;
           switch(x_option) {
                case 0:
                     val = priMax;
                     break;
                case 1:
                     val = rfMax;
                     break;
                case 2:
                     val = pwMax;
                     break;
           }

           return val;
      }
 }

使用return语句:

 public double xMax {
      get {
           double val = 0.00f;
           switch(x_option) {
                case 0:
                     return priMax;
                case 1:
                     return rfMax;
                case 2:
                     return pwMax;
           }
      }
 }

是否有性能差异和/或清理?

4 个答案:

答案 0 :(得分:2)

嗯,最重要的是你不要混合它们。

第一种形式的一个动机是它有一个退出吸气剂的点。如果代码比示例中的代码更复杂,那么这可能很有用,但是在这样的简单示例中它并不重要。

只要代码与示例中一样简单,第二种形式的简单性就是一个很好的论据。


你的第二个例子不像现在那样编译,因为代码可以到达属性的末尾而不返回任何内容。在第一种情况下,您可以在切换之前将变量设置为默认值,对于第二种情况,您应该在开关中使用默认选项,并且根本不需要变量:

public double xMax {
  get {
    switch(x_option) {
      case 0:
        return priMax;
      case 1:
        return rfMax;
      case 2:
        return pwMax;
      default:
        return 0d;
    }
  }
}

答案 1 :(得分:1)

这是一个品味问题,但我希望尽可能single point of return。它更容易调试,让您在更清楚地使用代码合同时检查前置和后置。

答案 2 :(得分:0)

这个问题是二代人。但我会回答它,因为这个问题过去一直困扰着我。

以下是您要查看的内容:语法A 语法B

您应该注意什么:整个代码中语法的一致性。

选择一种风格并坚持下去。这可以通过个人选择,团队选择,老板选择等方式来决定。在遇到瓶颈之前烦恼性能就是将马车推到马前。

作为代码和复杂性积累的一般结果,如果你遇到switch语句,那么有人在某处编写了错误的代码,并尝试在代码的一个纱球中处理很多事情。

一个例子:一个API调用返回JSON,它返回一个数组中的5个不同的值,你需要弄清楚如何处理它或根据你的需要选择什么数据。

大多数情况下,一旦有多次返回或ifs的可能性,您应该将代码分成几个小块。

以Jon Skeet的代码为例:

public int DoSomething(string input1, string input2)
 {
     int ret;

     // First simple case
     if (input1 == null || input2 == null)
     {

         ret = -1;
     }
     else
     {
         // Second simple case
         int totalLength = input1.Length + input2.Length;
         if (totalLength < 10)
         {
             ret = totalLength;
         }
         else
         {
             // Imagine lots of lines here, using input1, input2 and totalLength
             // ...
             ret = someComplicatedResult;
         }
     }
     return ret;
 }

<小时/> 让我们看看我们是否可以先使代码更具可读性。

private int someComplicatedTask(string input1, string input2){
    // Second simple case
    int ret = 0;
    int totalLength = input1.Length + input2.Length;
    if (totalLength < 10)
    {
        ret = totalLength;
    }
    else
    {
       // Imagine lots of lines here, using input1, input2 and totalLength
       // ...
       ret = someComplicatedResult;
    }
    return ret;
}

public int DoSomething(string input1, string input2)
 {
     return input1 == null || input2 == null ? -1 : someComplecatedTask(...);
 }

这应该会让你想知道,'为什么在输入可能为空的时候你会调用DoSomething?'。

注意问题是如何解决的。我所取得的就是让代码看起来更好。

以下是关于if条件我将如何处理它:

空输入的条件将移出到清理功能。或者只有在输入不为空时才会进行调用。

...
if(input1 != null && input2 != null){
    output = DoSomething(input1, input2);
}
...

public int DoSomething(string input1, string input2)
{
    int len = input1.Length + input2.Length;
    return len < 10 ? len : someComplecatedTask(input1, input2);
}

private int someComplicatedTask(string input1, string input2){
    // Imagine lots of lines here, using input1, input2
    // ...
    return someComplicatedResult;
}

因此,代码现在看起来更易于管理。代码可以只有两条通道,一切都很好。

现在让我们看看你的第一个代码片段。

public double xMax {
      get {
           double val = 0.00f;
           switch(x_option) {
                case 0:
                     val = priMax;
                     break;
                case 1:
                     val = rfMax;
                     break;
                case 2:
                     val = pwMax;
                     break;
           }

           return val;
      }
 }

离开我的头顶,这很糟糕有两个原因:
1.将来的某个时候,x_option会获得另一个值,你会在每次得到{}时寻找适当的变化 2. {}应该是直截了当的。 Set {}应包含设置适当值的条件。

所以代码应该看起来像这样:

public double xMax {
      set {
           double val = 0.00f;
           switch(value) {
                case 0:
                     val = priMax;
                     break;
                case 1:
                     val = rfMax;
                     break;
                case 2:
                     val = pwMax;
                     break;
           }
           xmax = value * val; // say // This makes break better in switch.
      }
      get { return xmax; }
 }

因为在打破你的情况之后,你可以做更多的事情(所有情况都是常见的)操作,然后这比返回更好。这个例子关于得到一个更好,因为设置你不知道值,所以你需要一个决策树。

但是在获取时,你的对象完全知道它包含什么,并高兴地回复所要求的内容。

现在,你的第二个代码示例根本没有意义。决定归还什么不是对象的责任。它应该返回它的内容。

在设定时,你不应该强行回归。

我希望这可以解决一些疑问,并提出更多问题,因为还有很多东西需要学习。

答案 3 :(得分:-1)

我在华沙军事技术大学的第一个编程课程,Eng。 ZbigniewWesołowski表示,该功能只能有一个返回点。这是对ANSI-C编程的介绍,但他也告诉我们,我们永远不应忘记,因为这是一个普遍的规则,无论我们必须发展什么语言。更重要的是,就像一个暴君,他如果他尝试 - 甚至一次 - 使用goto语句,在函数中间返回,或者在for循环中修改迭代器,那么我将永远不会通过他的考试。

这是一个老年人的困境,无论是否在中间返回。一些人声称它使代码更清晰,另一些则说它不优雅,应该避免。根据我的经验,我已经注意到,多次返回最常出现在java代码中,而c,c ++和c#程序员则更愿意避免这种情况。这不是一个规则,只是一个观察。

另一个观察是java语言鼓励紧凑语法。 Java IDE(例如eclipse)通常将默认格式化程序设置为将开括号放在同一行(只是一个简单的例子)。多次返回与该方法一致,允许进一步压缩代码。

对面的Visual Studio将新行上的左大括号作为唯一字符。它鼓励清晰,粗体的语法,长文件,许多空白或单个字符行。我不知道哪个更好,如果有的话。

基本上我在大学和家里的课堂上写C#。然后我更喜欢带有空行的长文件。

在我的公司,我编写java代码,然后我更喜欢更紧凑的风格,我习惯了。在公司,我们使用checkstyle通过统一的样式来保持良好的代码质量。并且经过多年的公司存在,在checkstyle中一直存在着不允许多次返回的规则。

我在stackoverflow上看过一篇文章,其中一些人发布了它对性能的影响。在答案中,他得到了一个简单的基准测试结果。事实上,没有太大的区别。

在我的编码实践中,我宁愿避免多次返回。但是你的整体决定取决于你的个人品味,经验,习惯,信仰和质量要求。