为什么使用yield return的此代码进行编译?

时间:2019-07-19 23:56:04

标签: c# ienumerable

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

public static IEnumerable<int> Foo()
{
}
  

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

但是,仅在编译时出现有关无法访问代码的警告:

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

这将产生一个空的枚举。为什么这样做有效,并且它是定义的行为?

1 个答案:

答案 0 :(得分:7)

public static IEnumerable<int> Foo()
{
}

第一个没有返回值(因此会出现编译器消息)。这很有意义-它没有足够的上下文来知道该怎么做。 它应该返回null吗?一个空的枚举?它不知道-因此它不会让您编译。

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

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

  

如果没有屈服点,编译器会假设   函数的结尾(就像return;正常情况下的语句   功能)

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

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

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