【问题标题】:Why does this code using yield return compile? [duplicate]为什么这段代码使用 yield return 编译? [复制]
【发布时间】:2019-11-28 22:28:15
【问题描述】:

如您所料,此代码会产生编译器错误:

public static IEnumerable<int> Foo()
{
}

并非所有代码路径都返回值

然而,这编译时只有一个关于无法访问代码的警告:

public static IEnumerable<int> Foo()
{
    if(false)
    {
        yield return 0;
    }
}

这会产生一个空的可枚举。为什么这会起作用,它是定义的行为吗?

【问题讨论】:

  • 哇,如果真的是这样的话,我会给 c# 编译器很多功劳。 @mjwills
  • @JamieTaylorSangerman 这几乎是相反的。编译器非常愚蠢——根据我的理解,它只是说“好吧,我看到了收益回报”。它不会尝试做过多的可达性分析等。

标签: c# ienumerable


【解决方案1】:
public static IEnumerable<int> Foo()
{
}

第一个没有返回(因此编译器消息)。这是有道理的——它没有足够的上下文来知道该做什么。 它应该返回null 吗?一个空的可枚举?它不知道——所以它不会让你编译。

public static IEnumerable<int> Foo()
{
    if(false)
    {
        yield return 0;
    }
}

第二个确实有一个yield return(即使无法访问),它提供了足够的上下文来知道您想要返回一个可枚举(因此它可以设置必要的状态机)。现在,当代码执行时,您实际上从未点击过yield return 行(因此会出现编译器警告) - 所以调用者将得到一个空的可枚举。 这是expected -

如果您没有 yield break,编译器会在 函数的结尾(就像一个正常的 return; 语句 函数)

鉴于第二个代码示例有多丑陋和不直观,您不妨改用:

public static IEnumerable<int> Foo()
{
    yield break;
}

自编译以来,其意图更加清晰,编译器不会抱怨无法访问的代码。

【讨论】:

  • 在我的真实代码中,条件测试了一个变量。我看了看我刚刚写的东西,想知道为什么我没有收到编译器错误。有趣的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-27
  • 2012-07-06
  • 2013-08-08
  • 1970-01-01
  • 2012-12-28
  • 2021-09-26
相关资源
最近更新 更多