C# 从迭代器块返回单个元素-迭代器不能包含return语句
假设我有下面的方法。有些人来了C# 从迭代器块返回单个元素-迭代器不能包含return语句,c#,.net,c#-4.0,iterator,yield,C#,.net,C# 4.0,Iterator,Yield,假设我有下面的方法。有些人来了 public IEnumerable<ValidationResult> Validate(UserLoginCommand command) { User user = userRepository.Get(u => u.Email == command.UserEmail); if(user != null) { if(!user.Activated)
public IEnumerable<ValidationResult> Validate(UserLoginCommand command)
{
User user = userRepository.Get(u => u.Email == command.UserEmail);
if(user != null)
{
if(!user.Activated)
{
return new IEnumerable<ValidationResult>() {new ValidationResult("NotActived", Resources.UserNotActivated)};
}
if(user.IsPasswordIncorrent)
{
yield return new ValidationResult("IncorrectPassword", Resources.IncorrentPassword);
}
}
}
我该怎么办呢?返回语句实际上不应该是一种收益吗
yield return ValidationResult("NotActived", Resources.UserNotActivated);
如果你真的需要返回一个集合,你也可以yield return
a collection(就像你拥有的一样),因为你只有一个集合,所以这是不必要的
此外,如果要停止显式枚举,可以使用
yieldbreak代码>如果您只想返回大小为1的集合,可以执行以下操作:
if(!user.Activated)
{
yield return new ValidationResult("NotActived", Resources.UserNotActivated);
yield break;
}
如错误消息所示,不能将yield return
语句和return
语句混合到一个方法中
您有两种通用方法:
这种方法应该得到热切的评价;您应该使用所有return
语句,找到将所有yield
语句转换为returns的方法
该方法应该使用延迟执行,找到一种方法将所有return
语句转换为yield
语句
在你的情况下,可能是#2,但在其他情况下,两者都可能是合适的
现在,如何将收益
转化为回报
:
将单个元素包装到某种类型的集合中,并返回:
return new[]{ someItemToReturn };
或
您可以使用屈服断裂
指示序列已结束,即使方法尚未达到其自然结束。注意,屈服断裂代码>应该很少使用。大量使用它会带来代码气味(但这似乎是一个合适的情况)
现在,理想情况下,我们应该有一个某种类型的yield-foreach
关键字,这样您就可以在迭代器块中生成一个集合,但是到目前为止,还没有这样的关键字添加到语言中。我认为错误消息非常明确。您不能将yield
和return
混合使用,因为函数的执行将推迟到调用迭代器时。我建议去掉yield
,只构建自己的枚举。我希望Jon Skeet或Eric Lippert会在这里插话,解释编译器无法处理这种情况的确切原因。谢谢,这是我需要的简单解决方案。感谢您的回复,我学到了一些有用的东西,这些东西在将来会很有用,但在这种情况下,我更愿意保持我在任何地方使用的相同模式(收益率回报率)但在特殊情况下只返回一个元素。保罗·菲利普斯的回答很简单,很有效。投票是肯定的。
return new[]{ someItemToReturn };
return Enumerable.Repeat<T>(someItemToReturn, 1);
foreach(var item in collectionYouWereReturning)
yield return item;