如您所料,此代码会产生编译器错误:
public static IEnumerable<int> Foo()
{
}
Run Code Online (Sandbox Code Playgroud)
并非所有代码路径都返回值
但是,此编译仅带有有关无法访问代码的警告:
public static IEnumerable<int> Foo()
{
if(false)
{
yield return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
这产生一个空的可枚举。为什么这样做有效,并且它是定义的行为?
public static IEnumerable<int> Foo()
{
}
Run Code Online (Sandbox Code Playgroud)
第一个没有返回(因此编译器消息)。这很有意义-它没有足够的上下文来知道该怎么做。它应该返回null吗?一个空的枚举?它不知道-因此它不会让您编译。
public static IEnumerable<int> Foo()
{
if(false)
{
yield return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
第二个确实有一个yield return(即使无法访问),它提供了足够的上下文来知道您要返回一个可枚举的对象(因此它可以设置必要的状态机)。现在,当代码执行时,您实际上不会碰到这一yield return行(因此会发出编译器警告)-因此,调用者将得到的是一个空的可枚举值。这是预期的 -
如果没有屈服中断,则编译器将在函数末尾假定一个(就像return;普通函数中的语句一样)
鉴于第二个代码示例多么丑陋和不直观,您可能希望使用:
public static IEnumerable<int> Foo()
{
yield break;
}
Run Code Online (Sandbox Code Playgroud)
由于它可以编译,因此其意图更加清楚,并且编译器将不会抱怨无法访问的代码。