为什么使用 yield return 的代码可以编译?
Why does this code using yield return compile?
如您所料,此代码会产生编译器错误:
public static IEnumerable<int> Foo()
{
}
not all code paths return a value
然而,这只编译了关于不可访问代码的警告:
public static IEnumerable<int> Foo()
{
if(false)
{
yield return 0;
}
}
这会生成一个空的可枚举对象。为什么这行得通,它是否定义了行为?
public static IEnumerable<int> Foo()
{
}
第一个没有 return(因此是编译器消息)。这是有道理的——它没有足够的上下文来知道该做什么。 应该returnnull
吗?一个空的枚举?它不知道 - 所以它不会让你编译。
public static IEnumerable<int> Foo()
{
if(false)
{
yield return 0;
}
}
第二个确实有一个 yield return
(即使无法访问),这给了它足够的上下文来知道你想要到return一个可枚举的(所以它可以设置必要的状态机)。现在,当代码执行时,您实际上并没有点击 yield return
行(因此出现编译器警告)——因此调用者将得到一个空的可枚举对象。
这是 expected -
If you don't have a yield break, the compiler would assume one at the
end of the function (just like a return; statement in a normal
function)
考虑到第二个代码示例有多丑 un-intuitive,您可能希望改用:
public static IEnumerable<int> Foo()
{
yield break;
}
自编译以来,其意图更加清晰,编译器不会抱怨无法访问的代码。
如您所料,此代码会产生编译器错误:
public static IEnumerable<int> Foo()
{
}
not all code paths return a value
然而,这只编译了关于不可访问代码的警告:
public static IEnumerable<int> Foo()
{
if(false)
{
yield return 0;
}
}
这会生成一个空的可枚举对象。为什么这行得通,它是否定义了行为?
public static IEnumerable<int> Foo()
{
}
第一个没有 return(因此是编译器消息)。这是有道理的——它没有足够的上下文来知道该做什么。 应该returnnull
吗?一个空的枚举?它不知道 - 所以它不会让你编译。
public static IEnumerable<int> Foo()
{
if(false)
{
yield return 0;
}
}
第二个确实有一个 yield return
(即使无法访问),这给了它足够的上下文来知道你想要到return一个可枚举的(所以它可以设置必要的状态机)。现在,当代码执行时,您实际上并没有点击 yield return
行(因此出现编译器警告)——因此调用者将得到一个空的可枚举对象。
这是 expected -
If you don't have a yield break, the compiler would assume one at the end of the function (just like a return; statement in a normal function)
考虑到第二个代码示例有多丑 un-intuitive,您可能希望改用:
public static IEnumerable<int> Foo()
{
yield break;
}
自编译以来,其意图更加清晰,编译器不会抱怨无法访问的代码。