[c#] 带IEnumerable的嵌套收益率回报



2 Answers

你可以像这样设置所有的错误来源(方法名称来自Jon Skeet的答案)。

private static IEnumerable<IEnumerable<ErrorInfo>> GetErrorSources(Card card)
{
    yield return GetMoreErrors(card);
    yield return GetOtherErrors();
    yield return GetValidationErrors();
    yield return AnyMoreErrors();
    yield return ICantBelieveHowManyErrorsYouHave();
}

然后你可以同时迭代它们。

private static IEnumerable<ErrorInfo> GetErrors(Card card)
{
    foreach (var errorSource in GetErrorSources(card))
        foreach (var error in errorSource)
            yield return error;
}

或者,您可以使用SelectMany压扁错误来源。

private static IEnumerable<ErrorInfo> GetErrors(Card card)
{
    return GetErrorSources(card).SelectMany(e => e);
}

GetErrorSources方法的执行也会被延迟。

Question

我有以下功能来获取卡的验证错误。 我的问题涉及处理GetErrors。 两种方法都有相同的返回类型IEnumerable<ErrorInfo>

private static IEnumerable<ErrorInfo> GetErrors(Card card)
{
    var errors = GetMoreErrors(card);
    foreach (var e in errors)
        yield return e;

    // further yield returns for more validation errors
}

是否有可能返回GetMoreErrors所有错误,而不必通过它们枚举?

考虑这可能是一个愚蠢的问题,但我想确保我不会出错。




我没有看到你的功能有什么问题,我会说它正在做你想做的。

把Yield看作每次被调用时在Enumeration中返回一个元素,所以当你在foreach循环中这样做时,每次调用它时都会返回1个元素。 你可以在你的foreach中添加条件语句来过滤结果集。 (仅仅通过不排除您的排除标准)

如果您稍后在方法中添加后续产量,它将继续向枚举中添加1个元素,从而可以执行如下操作...

public IEnumerable<string> ConcatLists(params IEnumerable<string>[] lists)
{
  foreach (IEnumerable<string> list in lists)
  {
    foreach (string s in list)
    {
      yield return s;
    }
  }
}



我很惊讶没有人想过在IEnumerable<IEnumerable<T>>上推荐一个简单的扩展方法来让这个代码保持延迟执行。 我是延迟执行的粉丝,原因很多,其中之一就是即使对于庞大的可枚举枚举,内存占用也很小。

public static class EnumearbleExtensions
{
    public static IEnumerable<T> UnWrap<T>(this IEnumerable<IEnumerable<T>> list)
    {
        foreach(var innerList in list)
        {
            foreach(T item in innerList)
            {
                yield return item;
            }
        }
    }
}

你可以像这样在你的情况下使用它

private static IEnumerable<ErrorInfo> GetErrors(Card card)
{
    return DoGetErrors(card).UnWrap();
}

private static IEnumerable<IEnumerable<ErrorInfo>> DoGetErrors(Card card)
{
    yield return GetMoreErrors(card);

    // further yield returns for more validation errors
}

同样,你可以在DoGetErrors附近DoGetErrors包装功能, DoGetErrors移动到callsite。




Related