kunjee
kunjee

Reputation: 2759

Refactor the foreach loop with continue in it?

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

Answers (3)

lazarus
lazarus

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

Carl Manaster
Carl Manaster

Reputation: 40356

At the start of the loop, set a boolean - let's call it escape to false.. Now replace all of your existing continues 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 continues), 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

Yochai Timmer
Yochai Timmer

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

Related Questions