Проверяется ли takewhile () каждую итерацию, используя что-то вроде yeild, или он просто захватывает набор элементов одновременно? - PullRequest
0 голосов
/ 16 сентября 2018

например, скажем, я хочу сделать что-то вроде этого:

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
}

Теперь, это равносильно этому:

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
}

Этот второй пример ведет себя как первый, или он всегда пропускает весь цикл? Как продолжение, если я все еще хочу использовать foreach, действительно ли я должен использовать разрыв, чтобы обойти это? Кроме того, извините, если я сделал что-то глупое в этих примерах, я пытаюсь упростить версию алгоритма поиска пути, который я пишу, и это был самый простой пример, который я мог придумать, чтобы задать этот вопрос ...

1 Ответ

0 голосов
/ 16 сентября 2018

Как документация Microsoft здесь :

TakeWhile (IEnumerable, Func) Метод проверяет каждый элемент источника с помощью предиката и возвращает элемент, если результат верен. Перечисление останавливается, когда предикат функция возвращает false для элемента или когда источник больше не содержит элементы.

и это декомпилированный метод TakeWhile ():

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;
  }
}

Как видите, метод TakeWhile () проходит через все элементы, выполняющие проверку, и его внутренний цикл не имеет отношения к вашему внешнему циклу.

...