产生相同数据类型的另一个Enumerable的返回结果
本文关键字:另一个 Enumerable 返回 结果 数据类型 | 更新日期: 2023-09-27 18:24:25
我正在编写验证逻辑,我希望调用者只获得他们真正需要的验证消息的数量(在某些情况下,只需要第一条验证消息,而在其他情况下,我们希望现在解决给定数据的所有问题)
考虑到这一点,我想"太棒了!我将返回一个IEnumerable,并使用yield返回每个结果。如果在枚举中使用FirstOrDefault(),则只执行第一个失败的验证,其中将跳过以下内容,除非我们对验证结果enumerable调用ToList()。
我看到的问题是,如果我想把我的验证逻辑分解为多个方法,每个方法都返回一个Enumerable,我必须在那个集合上枚举,并在那里返回另一个yield。(见下面的简化示例)
public IEnumerable<string> Validate(ClassToValidate obj)
{
if(string.IsNullOrEmpty(obj.Name)
{
yield return "empty name";
}
foreach(var message in ValidateSubObject(obj.OtherObjectToValidate))
{
yield return message;
}
}
private IEnumerable<string> ValidateSubObject(OtherClass objToValidate)
{
yield return ...
}
我是否缺少其他关键字,可以从返回相同数据类型的另一个IEnumerable的其他方法中"产生返回集"?有比更简单的语法吗
foreach(var message in ValidateSubObject(obj.OtherObjectToValidate))
{
yield return message;
}
不能yield return
多个项目。如果你想使用迭代器方法来连接序列,你必须循环它们。
当然,您总是可以完全放弃yield return
,并构造您的IEnumerable<T>
以使用其他方式返回(LINQ的Concat
方法立即出现)。
public IEnumerable<string> Validate(ClassToValidate obj)
{
var subObjectMessages = ValidateSubObject(obj.OtherObjectToValidate);
if (string.IsNullOrEmpty(obj.Name))
{
return new[] { "empty name" }.Concat(subObjectMessages);
}
return subObjectMessages;
}
一旦在函数中引入了yield
,就必须继续使用它。目前常用的方法是使用LINQ,它通常更灵活。
public IEnumerable<string> Validate(ClassToValidate obj)
{
return (String.IsNullOrEmpty(obj.Name) ? new [] { "empty name" } : Enumerable.Empty<string>())
.Concat(ValidateSubObject(obj.OtherObjectToValidate));
}