Reputation: 2759
I was trying to refactor a very long foreach
loop. I got stuck as at few places I am having continue
in it. Here is some dummy code to mimic my original code
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
}
Here I have remove all the do something part in to separate function. But again I am having few code portion having continue
in it, that is breaking loop and moving forward to next element. So, I was unable to separate that part.
Again, here I am having constraint like steps are in continuation. Means first thing happens then second one and then third one then next... So, I can't move the position of code as of now. Because of that my function got big, around 300 lines and it is now getting hard to change or maintain.
Please provide a good solution for removing continue
or another way to break
method by changing the way of coding.
Please let me know if any other details are needed.
Upvotes: 2
Views: 3113
Reputation: 383
You dont mention whether the if implementation of your DoSomething() calls share args and return types, if they do, an alternative option would be to create a collection of Funcs containing your DoSomething() logic, and instead of lots of if statements you could just loop over the Func implementations until the return value dictates you should break.
var somethingFuncs = new List<Func<x, bool>>
{
DoSomething,
DoSomethingB,
Blah....
};
foreach(var something in somethingFuncs)
{
var result = something(arg);
if (result)
{
break;
}
}
Upvotes: 0
Reputation: 40356
At the start of the loop, set a boolean - let's call it escape
to false.. Now replace all of your existing continue
s with an assignment of escape
to true. This, by itself, isn't a true refactoring - it changes the behavior of the existing code - but we are only partway done. Now select the body of the loop (now with no continue
s), and extract it as a method. In the extracted method, replace each assignment of escape
with a return
statement. Eliminate the original creation of the escape
variable, and your code is in a state that is easier to further refactor.
Upvotes: 2
Reputation: 49271
Just refactor the if blocks into separate functions with appropriate names.
Then put all the ifs inside eachother instead of the continue.
if (!something)
{
DoFirstThing();
if (!otherthing)
{
DoSechondThing();
}
}
//continue implicitly happens here anyway.
Upvotes: 2