首页 > 解决方案 > takewhile() 是使用 yeild 之类的方法检查每次迭代,还是一次抓取一组元素?

问题描述

例如,假设我想做这样的事情:

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,我真的必须使用 break 来解决这个问题吗?另外,对不起,如果我在这些示例中做了一些愚蠢的事情,我正在尝试简化我正在编写的寻路算法的一个版本,这是我能想到的最简单的示例来问这个问题......

标签: linqloopsforeachbreakc#-7.0

解决方案


作为微软在这里的文档:

TakeWhile(IEnumerable, Func) 方法使用谓词测试 source 的每个元素,如果结果为真,则生成该元素。当谓词函数为元素返回 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() 方法循环遍历所有进行检查的元素,并且它的内部循环与您的外部循环无关。


推荐阅读