【问题标题】:What is the better pratice: duplicate code or use goto statement? [closed]更好的做法是什么:重复代码或使用 goto 语句? [关闭]
【发布时间】:2014-03-27 13:39:19
【问题描述】:

我现在正在学习C#,遇到以下情况,有什么更好的做法,复制“EX 1”之类的代码还是使用“EX 2”之类的goto语句? 我不想要个人意见。

        // EX 1: 

        switch (a)
        {
            case 3:
                b = 7;
                c = 3; // duplicate code <-|
                break; //                    |
            case 4:    //                    |
                c = 3; // duplicate code --|
                break;
            default:
                b = 2;
                c = 4;
                break;
        }


        // EX 2: 

        switch (a)
        {
            case 3:
                b = 7;
                goto case 4; // not duplicate code and use goto statement
            case 4:
                c = 3;
                break;
            default:
                b = 2;
                c = 4;
                break;
        }

【问题讨论】:

  • 引用C# language specifications,“当一个switch 部分的执行之后是另一个switch 部分的执行时,必须使用显式的goto casegoto default 语句”。跨度>
  • 在这个特殊的例子中(总共 3 个案例),我更有可能使用 if/else 构造。
  • 您提出了一个需要个人意见(“哪个更好”)的问题,但声明您“不想要个人意见”。下定决心 - 你不能两全其美。
  • 理想情况下,我会说 a、b 和 c 是相关的,因此应该在类或类的方法中,然后将整个事情排除在外。除非花费很少的精力,否则我喜欢我的箱子是一个衬里,但这是个人喜好。

标签: c# goto


【解决方案1】:

这真的取决于。

案例 3 是案例 4 的特例吗?

在这种情况下,goto 可能是合适的,因为如果我们稍后在案例 4 中添加一些新行为,那么我们也会为案例 3 自动获得该行为。

如果案例 3 和 4 不相关,那么复制代码会更好。

如果你的实际案例这么小,那么几行,我宁愿复制代码,因为它简单易读。

【讨论】:

    【解决方案2】:

    示例 1 的优缺点

    + 通用结构 +简单易懂的逻辑 - 更多的代码行 - 代码重复

    示例 2 的优缺点

    + 更少的代码行 + 无代码重复 - 逻辑复杂 - 在生产代码中不常用

    底线

    我更喜欢示例 1,因为在这种特殊情况下,节省的费用很少,但逻辑变得更加复杂。 Goto 可以说,随着代码难度的增加,如果更多人开始编写相同的代码,则会增加出现错误的机会。让我们看看this embarrassing bug。如果开发者没有使用goto,就不会有这样的问题!

    奖励积分

    • 您可以使用enums 进行案例选择,所以case 3: => case CarPart.SteeringWheel
    • 确保每个case 都有一个break;
    • 确保有default 案例
    • 考虑使用多态性和继承而不是switch case

      ICarPart part1 = new SteeringWheel();
      ICarPart part2= new Mirror();
      var parts = new List<ICarPart>() {part1, part2};
      
      // now call your original method on the parts
      // no more need for a switch case 
      

    【讨论】:

    • 您链接的错误与goto 无关,但与使用不带大括号的if 子句有关。此外,使用 goto 进行清理是 C 中常见且公认的习语。
    • C 中确实用的很多。但不是在 C# 中。而且它是ifgoto的组合,所以我不会说它与goto无关`
    【解决方案3】:

    我个人不喜欢goto,因为它使您的代码更不容易理解和重现。

    我认为您的第一个代码示例没有大问题。如果需要,您还可以拆分 bc 的处理。

    你应该考虑什么更重要:

    • 代码可读性;
    • 最少的代码行数;
    • 此代码多久更改一次?当它发生很大变化并且依赖关系可能会丢失时,您可能不想使用goto

    【讨论】:

      【解决方案4】:

      一般来说,使用gotoconsidered to be bad practice(这是理所当然的),但使用goto 仅用于向前跳出结构化控制语句通常被认为是可以的,特别是如果替代方案是有更多复杂的代码。

      这是一个例子:

      for (...) {
          for (...) {
              ...
              if (something)
                  goto end_of_loop;
          }
      }
      
      end_of_loop:
      

      Here 你检查了goto 的其他一些可接受的用法。

      因此,goto 将被视为一种不好的做法。但是,正如我所说,它仍然可以使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-12
        • 1970-01-01
        • 1970-01-01
        • 2022-01-21
        • 2017-01-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多