请考虑下面这个非常小的方法 -:
IEnumerable<ObjectTest> CreateObjectList()
{
bool aTest = false;
ObjectTest anObject = null;
if (aTest == true)
{
foreach (var item in aTestList)
{
yield return anObject;
}
}
}
我觉得这段代码不应该编译。当布尔测试失败时,有些路径不会返回。编译器应该报告-:
并非所有代码路径都会返回值。
但事实并非如此 - 有人可以解释一下吗?
(.NET 4.0)
理查德
仅仅因为您使用
yield return
并不意味着它涵盖了代码中超出 yield return
范围的所有路径。
扩展 HimBromBeere 在评论中所说的内容,请考虑以下内容:
IEnumerable<ObjectTest> CreateObjectList()
{
bool aTest = false;
ObjectTest anObject = null;
List<ObjectTest> objects = new List<ObjectTest>();
if (aTest == true)
{
foreach (var item in aTestList)
{
objects.Add(anObject);
}
return objects;
}
}
这基本上就是您正在做的事情,只允许“从内部”处理代码的
foreach
部分。上面的代码会抛出同样的错误。
正如评论中所说,您缺少的部分是,当您的
if (aTest == true)
无效时,其余代码不会返回任何内容。您可以维护上面的代码,但只需包含以下内容:
if (aTest == true)
{
...
}
yield break;
请记住,您用 C# 编写的内容不一定是经过编译的。
yield
关键字是那些“语法糖”之一,它不会产生与您所写内容完全相同的结果。
尝试使用.Net反编译器(例如JustCode或dotPeek)打开编译后的代码,并检查IL(中间语言)结果。你会发现编译出来的并不是你所期望的。
简而言之,
yield return
只是“创建变量,填充它,然后返回它”的快捷方式。
您可以在这里看到更多解释:http://www.dotnetperls.com/yield
想想如果在以下情况下 aTestList 为空会发生什么:
IEnumerable<ObjectTest> CreateObjectList()
{
foreach (var item in aTestList)
{
yield return item;
}
}
你知道会发生什么吗?枚举器不会产生任何结果。这正是您问题中的代码中发生的情况。