2013-03-24 106 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; 
    } 
}