-1

for instance, let's say I want to do something like this:

bool foo(List<strings> stringList, int counter)//assume this list has, like, 10 elements, and counter=3, idk
{
    bool found= false;
    for(int i=0; i<stringlist.Count && !found; i++)
    {
        if(stringlist[i].length < 2 || counter >=6)
            found=true;
        counter++;
    }
    return found
}

Now, Is that equivelent to this:

bool foo(List<strings> stringList, int counter)//assume this list has, like, 10 elements, and counter=3, idk
{
    bool found= false;
    foreach(string s in stringlist.Takewhile(x=> (!found)))
    {
        if(s.length < 2 || counter >=6)
            found=true;
        counter++;
    }
    return found
}

Does this second example behave like the first, or does it always skip the whole loop? As a follow up, if I still want to use a foreach, do I really have to use a break to get around this? Also, sorry if I did something dumb in these examples, I am trying to simplify a version of a path-finding algo I am writing and this was the simplest example I could think of to ask this question...

Firestar9114
  • 432
  • 4
  • 9
  • Observation: It would have taken you less time to put a breakpoint in the `TakeWhile` lambda expression and run the code yourself to find out, than it would have done to write this question. – Richardissimo Sep 17 '18 at 22:08

1 Answers1

1

As the documentation of Microsoft here :

The TakeWhile(IEnumerable, Func) method tests each element of source by using predicate and yields the element if the result is true. Enumeration stops when the predicate function returns false for an element or when source contains no more elements.

and this is the decompiled TakeWhile() method :

public static IEnumerable<TSource> TakeWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
  if (source == null)
    throw Error.ArgumentNull(nameof (source));
  if (predicate == null)
    throw Error.ArgumentNull(nameof (predicate));
  return Enumerable.TakeWhileIterator<TSource>(source, predicate);
}

private static IEnumerable<TSource> TakeWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
  foreach (TSource source1 in source)
  {
    if (predicate(source1))
      yield return source1;
    else
      break;
  }
}

as you can see, yes the TakeWhile() method loops through all the elements doing the check and it's internal loop is irrelevant to your outer loop.

Mojtaba Tajik
  • 1,725
  • 16
  • 34
  • Does this mean it loops through all the elements doing the check regardless of the outer "foreach" loop though? That is what I don't understand in the documentation for TakeWhile. – Firestar9114 Sep 16 '18 at 04:33
  • Ah, I see, that answers my question. Thanks. Guess I'll have to figure out another way to write this :) – Firestar9114 Sep 16 '18 at 04:45
  • It has since been brought to me attention that it's internal loop is NOT irrelevant to the outer loop. Depending on the value of found in the outer loop in this case the internal will return a different value. Still, thank you for being polite about this, even though this mislead me this was still sadly easily my most positive experience with this sites toxic community. – Firestar9114 Sep 26 '18 at 22:16