2010-07-07 31 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#的問題!)