2013-03-24 156 views
1

我試圖重構一個非常長的foreach循環。我被困在幾個地方,其中有continue。這裏是一些虛擬代碼來模仿我的原代碼重構foreach循環並繼續嗎?

IEnumerable<dynamic> allData = FetchAllData(); 
IEnumerable<dynamic> relativeData = FetchAllRelativData(); 

foreach (var rdata in relativeData) 
{ 
    IEnumerable<dynamic> dataTobeProcessed = allData.Where(c => c.Name = rdata.Name); 

    //Do something 

    //if then Continue 

    // do something 

    //if then continue 

    // do something 

    // do something 

    // add data to db 
} 

這裏我已經刪除了所有做某件事情分開的功能。但是我又有幾個代碼部分,其中有continue,這是斷開循環並前進到下一個元素。所以,我無法分開那部分。

再一次,在這裏我有像步驟的約束是在繼續。意思是第一件事發生在第二件事,然後是第三件事,然後接下來......所以,我現在不能移動代碼的位置。因爲我的功能很大,大約有300條線路,現在變得很難改變或維護。

請通過改變編碼方式,爲刪除continue或另一種方法break方法提供一個很好的解決方案。

請讓我知道是否需要任何其他細節。

+0

你可以發佈整個方法嗎?我知道300行很長,但也許這有助於更多然後評論 – bas 2013-03-24 08:55:18

回答

2

只需將if塊重構爲具有適當名稱的單獨函數即可。
然後把所有的ifs放在eachother裏面而不是continue。

if (!something) 
{ 
    DoFirstThing(); 
    if (!otherthing) 
    { 
    DoSechondThing(); 
    } 
} 
//continue implicitly happens here anyway. 
+0

如果我正確地理解你,我應該移動其他所有東西,然後如果和繼續吧? – kunjee 2013-03-24 05:37:41

2

在循環的開始,設置一個布爾 - 姑且稱之爲escape爲false。現在用的escape爲true分配替換所有現有continue S的。這本身並不是真正的重構 - 它改變了現有代碼的行爲 - 但我們只是完成了一部分。現在選擇循環的主體(現在沒有continue s),並將其作爲方法提取。在提取的方法中,將escape的每個賦值替換爲return語句。消除escape變量的原始創建,並且您的代碼處於更容易進一步重構的狀態。

0

你不提,如果您實現DoSomething的()是否調用共享指定參數和返回類型,如果他們這樣做,另一種選擇是創建一個包含DoSomething的()邏輯funcs中的一個集合,而不是很多if語句可以循環使用Func實現,直到返回值指示您應該中斷爲止。

var somethingFuncs = new List<Func<x, bool>> 
{ 
    DoSomething, 
    DoSomethingB, 
    Blah.... 
}; 

foreach(var something in somethingFuncs) 
{ 
    var result = something(arg); 

    if (result) 
    { 
    break; 
    } 
}