2010-07-07 33 views
2

我正在用.Net Framework 2.0在C#中重写旧的VB6程序(不是我的选择,它是由公司决定的)。大部分情况都非常好。该程序测量来自精密磨床的输入数据,并显示图形和刻度以显示精度。可以使用GoTo吗?

原程序员是机械工程师,但不是软件工程师。该程序的工作原理,但在这里和那里有一些草率的代码。最值得注意的是,我遇到了几个GoTo语句。在必要的地方将事物放在循环中很容易,并且可以从中获得相同的功能。

但是,我在原始代码中遇到了一个案例,它似乎像GoTo所做的不仅仅是模拟一个循环。它有几个不同的退出条件。它看起来是这样的(而不是实际的代码,只是一些简短我做了演示):

VB6代码

Public Sub Tick() 
    Dim condition1 As Boolean 
    Dim condition2 As Boolean 
    Dim testNumber As Integer 

    beginning: 'The GoTo label' 

    ' (... Some Other Code Here ...)' 

    If condition1 = True Then 
     goto beginning 
    Else 
     ' (... Do some calculation ...)' 
    End If 

    If condition2 = True Then 
     ' (... Do some calculation ...)' 
     goto beginning 
    End If 

    Select Case testNumber 
     Case 1: '(... Some code ...)' 
     Case 2: '(... Some code ...)' 
     Case 3: '(... Some code ...)' 
     Case 4: goto beginning 
    End Select 
End Sub 

实际的代码可能比那几个更小的条件,但其基本思想是有几个不同的事情导致它回到自身。有没有一种好的方法可以为这样的情况编写一个循环,或者这是一个goto语句可以接受的情况? (不可否认,一个非转向解决方案将是首选)。

感谢您的时间和考虑。

注意:我尝试使用一段时间(真正)循环与休息;声明,但它导致程序陷入无限循环并锁定。会不会建议编写一个包含多个条件的长时间循环(使用和/或等)?

+0

你尝试了while循环,但是你必须犯这个错误,因为你不应该以无限循环结束。我可以看到这个函数带有一些嵌套的while循环,因为它是疯狂的。这个或者'一些代码'和'计算'的东西应该被移到函数中,并称为IF条件。 – Fosco 2010-07-07 15:28:54

+1

你可能想尝试递归。 – DevinB 2010-07-07 15:28:55

回答

6

A while(true)循环应该没问题,如果你在它的末尾有中断并且continue以前有任何转到的地方。但是,这绝对只是第一步 - 这听起来像是一个有力的重构。

+0

然后,我将继续使用while(true)语句。至于完全重写代码,这是不可能的。我是一名三年级的实习编程学生,所以我只用了几个月的时间来处理给我的代码。我已经完成了我所接触到的内容,但缺乏经验是一个问题。 – KChaloux 2010-07-07 15:33:41

+0

使用while(true)循环有没有任何可能的附加好处?我只问,因为你基本上有不同的措辞具有相同的功能。 – FromCanada 2010-07-07 15:45:47

+0

'do {...} while(false);'循环会更好;最后不需要“休息”。除此之外,是的,重构是按顺序的。 – 2010-07-07 15:46:12

0

我会把它包装在一个单元测试中,并通过它触发各种值并记录结果是什么。

然后,当您将代码重构为C#时,可以使用测试结果来验证您的操作。

1

开始通过把该循环的身体变成一个独立的功能,并更换goto s的'回报的 - 或prehaps几个独立的功能:

If condition1 = True Then 
    goto beginning 
Else 
    ' (... Do some calculation ...)' 
End If 

应该成为

If not condition1 
     DoSomeCalculation() 
End If 

很快将出现什么时候退出的逻辑关系&何时退出。当发生这种情况时,重构这段代码应该像你已经做的那样变得微不足道。

0

虽然这种情况看起来已经足够用于do/while true循环,但我看到了一些不是的情况。

除了词法分析器或其他FSA机制之外,我认为每2000行不止一个goto意味着你做错了什么。

当然,如果你有一个反复出现的习语有goto这是另一个故事,因为反复出现的习语会覆盖样式规则。成语=一致,一致=可读。

1

我认为你的第一步应该是将所有的'(do some code)'解压到他们自己的方法中。一旦你完成了,实际的代码流将变得更清晰一些。

取决于它是如何嵌套的,有几种可能的方法来完成这个(没有实际代码硬)。

(我是一个C#编码器,我不知道VB,请原谅)

递归

Public Sub Tick() 
    Dim condition1 As Boolean 
    Dim condition2 As Boolean 
    Dim testNumber As Integer 

    If basecase = True Then 
     return; 
    EndIf 

    ExecuteInitialzerStuff(); 

    If intialized = False Then 
     Tick(); 
     return; 
    Else 
     ExecuteAffirmationStuff(); 
    End If 

    If affirmed = True Then 
     ExecutePostAffirm(); 
     Tick(); 
     return; 
    End If 

    Select Case testNumber 
     Case 4: Tick(); 
    End Select 
End Sub 

另一个选择是打破每个选项为离散码流

Public Sub Tick() 
    Dim condition1 As Boolean 
    Dim condition2 As Boolean 
    Dim testNumber As Integer 

    If condition1 = true Then 
     Tick_Condition1(); 
     return; 
    EndIf 

    If condition2 = true Then 
     Tick_Condition2(); 
     return; 
    EndIf 

    Tick_Switch(testNumber); 

一旦你分解了每个代码段试图完成的每个单独的任务,它应该很清楚应该完全删除这个方法,并且将int o几个单独的Tick()方法,每个方法都调用TickInit() TickDestroy(), TickSkyFalling();或其他任何方法,具体取决于具体情况。

我认为试图重构这个函数是错误的决定。但是我不能确定没有看到实际的代码。

+0

实际的代码是...有点可怕。我不确定它为什么存在。据我所知,他试图制造一个计时器......而没有真正制定计时器。它连续循环回转,递增一个整数直到某个点,然后重置它以模拟一个时间间隔,并使用DoEvents()释放CPU。 这是奇怪的,因为它在程序的另一部分使用了一个计时器就好... – KChaloux 2010-07-07 15:58:00

+1

@KChaloux完全。我认为在这种情况下,你应该把函数*解析成容易理解的位。然后,一旦你确定你明白了它是什么*尝试*做的,重写它不同。有时,GOTO可以很容易地变成一个循环,或在极少数情况下按原样合理使用。在你的情况下,GOTO不是函数的问题,它是函数本身。 – DevinB 2010-07-07 17:14:21

1

在switch语句:

 switch (groupMembershipStatus) 
     { 
      case SocialGroupMembershipStatus.Banned: 
       return redirect(); 
      case SocialGroupMembershipStatus.MembershipRequestDenied: 
       Abc(); 
       goto case SocialGroupMembershipStatus.Banned; 
     } 

(正如你看到的我只是在生产代码中写了一个跳转,我想知道是否有这个使用goto语句一个C#的问题!)