我具有以下功能来获取卡的验证错误。我的问题与处理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
中的所有错误?
考虑这可能是一个愚蠢的问题,但我想确保自己没有错。
这绝对不是一个愚蠢的问题,F#支持整个集合使用yield!
,而单个项目使用yield
。 (就尾递归而言,这可能非常有用...)
很遗憾,C#不支持。
但是,如果有几种方法每个都返回一个IEnumerable<ErrorInfo>
,则可以使用Enumerable.Concat
使代码更简单:
private static IEnumerable<ErrorInfo> GetErrors(Card card)
{
return GetMoreErrors(card).Concat(GetOtherErrors())
.Concat(GetValidationErrors())
.Concat(AnyMoreErrors())
.Concat(ICantBelieveHowManyErrorsYouHave());
}
尽管这两种实现之间有一个非常重要的区别:即使每次只使用一个返回的迭代器,它也会立即调用所有方法。您的现有代码将一直等到它循环遍历GetMoreErrors()
中的所有内容,然后甚至对下一个错误进行[[asks]。
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
中方法的执行也会延迟。
yield_
摘要: