如您所料,此代码会产生编译器错误:
public static IEnumerable<int> Foo()
{
}
并非所有代码路径都返回值
但是,仅在编译时出现有关无法访问代码的警告:
public static IEnumerable<int> Foo()
{
if(false)
{
yield return 0;
}
}
这将产生一个空的枚举。为什么这样做有效,并且它是定义的行为?
答案 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;
}
自编译以来,其意图更加清晰,并且编译器不会抱怨代码无法访问。