【问题标题】:yield return weird behavior收益返回奇怪的行为
【发布时间】:2013-12-11 11:06:04
【问题描述】:

我有以下代码:

virtual public IEnumerable<string> GetSelectedIds(){
   if (_kids == null)
        yield return null;
   foreach (var current in _kids.Nodes)
        yield return current;
}

这段代码在_kids.Nodes 崩溃,NullPointerException if _kids == null

如果_kids == null,我希望此方法在前置条件级别返回,但事实并非如此!

问题

为什么方法开头的前置条件不起作用?

【问题讨论】:

  • yield return 不会停止枚举 - 您应该按照金刚的建议使用 yeild break
  • 如果_kids == null,你会考虑返回一个空序列吗?
  • @AhmedKRAIEM 是的,那应该很好。

标签: c# ienumerable yield yield-return


【解决方案1】:

试试这个:

virtual public IEnumerable<string> GetSelectedIds(){
   if (_kids == null){
      yield return null;
      yield break;
   }
   foreach (var current in _kids.Nodes)
      yield return current;
}

【讨论】:

  • +1!感谢你及时的答复。但是,我觉得yield return null 是多余的。
  • @GETah 是的,这取决于 OP。我认为只是让它yield break; 更好。
  • 确实如此。顺便说一句,我是 OP :D
  • @GETah 啊,我什至没有注意到这一点:),是的,如果你愿意,可以删除它。
【解决方案2】:

改变

if (_kids == null)
        yield return null;

if (_kids == null)
        yield break;

这将返回一个空序列,用户不必检查返回值。

或者你可以重写为

public IEnumerable<string> GetSelectedIds(){
   if (_kids == null)
        return null;

   return GetSelectedIds2();
}

private IEnumerable<string> GetSelectedIds2()
{
    foreach (var current in _kids.Nodes)
        yield return current;
}

【讨论】:

  • 不 - 如果 _kidsnull,则 OP 希望从枚举器返回 null
  • @lazyberezovsky OP 没有这么说,我认为最好返回一个空序列。
  • +1!感谢您的快速回答,这可能是最好的答案,因为我需要返回一个空的枚举来代替:)
  • @lazyberezovsky 我敢打赌他不会。即使他认为他愿意,他也不应该愿意......
  • @WillDean 同意,我倾向于不从方法返回空值。但我不明白为什么 OP 这样做(他可以使用简单的 if..else 而不产生任何东西)
【解决方案3】:

你的yield return null 几乎肯定不是你想要的——它不会停止迭代的运行(正如你所发现的那样),而且你可能不想将空字符串返回到集合中。

只需将其替换为 yield break 即可。这样你会得到一个空集合。

或者将foreach 包裹在if(_kids != null) 中,这样可能会更清楚。

至于为什么前提条件不会停止执行——这就是yield return 的工作方式——想象一下这样的方法:

IEnumerable<String> GetStrings()
{
   yield return "MyFirstString";
   yield return "MySecondString";
   yield return "MyThirdString";
}

这将返回三个字符串的集合 - 即它不会在第一个 yield return 之后停止。

【讨论】:

  • 或者更简单,在foreach之前插入else
  • 如果您使用yield break,您的if(_kids != null) 也将是多余的。这就是我评论的全部内容(在您扩展答案之前)。
猜你喜欢
  • 2019-07-06
  • 2019-01-24
  • 2012-12-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
  • 1970-01-01
  • 1970-01-01
  • 2013-05-31
相关资源
最近更新 更多