0

I just stumbled over a problem while programming which would really benefit from a goto like structure. Consider this example:

//tries to find a solution for a problem 3 times
//in this process copies elements from old to newList
foreach (var tryNbr in Util.range(0,3)) 
{
    List<A> newList = new List<A>();
    List<A> oldList = workList;
    while(oldList.Count != 0)
    {
        List<A> possibleMatched = FINDWITHLINQSTUFF;
        //try stuff out

        if(possibleMatches.Count == 0)
            break;

        //do more stuff
    }

    if(oldList.Any())
    {
        workList = newList;
        return true;
    }
}

So the problem i have here is, that in my while loop, i need to check for some condition, and if it is true i want to continue from the next foreach iteration, since my whole previous process did not work also.

Since neighter break or continue can do this, i need to check for an extra condition behind my while, which is pretty prone to errors, if i might change something later without giving the attention needed.

Is there a contruct like

goto foreach;

or

continue foreach;

Which continues from the next outer foreach loop? Would it actually be a viable solution to use a goto here (and incrementing the counter manually?

PS: Do you have a better solution for the general structure of this Code?

Xlaech
  • 456
  • 3
  • 19
  • 1
    I am not sure if I understand the problem correctly, but one way to do this is to define a variable bool someConditionMet = false; and then you set it to be true inside the while loop, and check it's value outside the while loop. Goto might be a solution, but it is typically not recommended for readability reasons, and possibly call stack reasons (not sure if that's the case in c#). – Husain Mar 17 '16 at 16:51
  • @Husain `goto` is quite safe in C#. Readability... might be better with a `goto` than a local. Of course, it can make future refactoring harder - in particular, `goto` will not work across methods (which is a good thing). – Luaan Mar 17 '16 at 16:57
  • 1
    Eric Lippert discusses the merits of whether `continue` itself is any better than `goto` in the linked Q&A, and moreso in his blog post linked from that answer. – James Thorpe Mar 17 '16 at 16:58
  • 1
    _Is goto always evil?_ No. It is perfectly fine to use it __to jump forward and out of a deeply nested loop or condition__. – TaW Mar 17 '16 at 17:11
  • @JamesThorpe Thank you for the suggestion. I read the article and it was very usefull. – Xlaech Mar 17 '16 at 19:36
  • @TaW i actually went with a goto solution, since it is the easiest to service. But the Method extraction is also pretty good. – Xlaech Mar 17 '16 at 19:38

1 Answers1

1

If the result of the while loop should control (i.e. continue) the foreach loop, design it as such:

bool WhateverMethod() 
{

    //tries to find a solution for a problem 3 times
    //in this process copies elements from old to newList
    foreach (var tryNbr in Util.range(0,3)) 
    {
        List<A> newList = new List<A>();
        List<A> oldList = workList;

        if (Matched(oldList, newList))
            continue;

        if(oldList.Any())
        {
            workList = newList;
            return true;
        }
    }
}

bool Matched(List<A> oldList, List<B> newList)
{
   while(oldList.Count != 0)
    {
        List<A> possibleMatched = FINDWITHLINQSTUFF;
        //try stuff out

        if(possibleMatches.Count == 0)
            return false;

        //do more stuff
    }

    return true; // I'm assuming?
}

This doesn't address the usage of goto, or the question "is it always evil" but I would suggest that goto is "always" or "almost always" unnecessary.

clarkitect
  • 1,720
  • 14
  • 23