请考虑以下非常小的方法 - :
IEnumerable<ObjectTest> CreateObjectList()
{
bool aTest = false;
ObjectTest anObject = null;
if (aTest == true)
{
foreach (var item in aTestList)
{
yield return anObject;
}
}
}
我觉得这段代码不应该编译。布尔测试失败时,有些路径不返回。编译器应该报告 - :
并非所有代码路径都返回值。
但事实并非如此 - 有人可以解释一下吗?
(。NET 4.0)
理查德
答案 0 :(得分:3)
当yield return
返回迭代器时,无论如何都保证永远不会返回null
。因此,yields
总是具有返回值的方法,即迭代器。在迭代器中返回任何元素与否在此处不相关。
答案 1 :(得分: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;
}
}
这基本上就是你正在做的事情,只允许从&#34;内部进行处理。代码的foreach
部分。上面的代码会抛出相同的错误。
正如评论中所述,您错过的部分是,当您的if (aTest == true)
无效时,其余代码都不会返回任何内容。您可以维护上面的代码,但只需包含以下内容:
if (aTest == true)
{
...
}
yield break;
答案 2 :(得分:0)
考虑在下列情况下如果aTestList为空会发生什么:
IEnumerable<ObjectTest> CreateObjectList()
{
foreach (var item in aTestList)
{
yield return item;
}
}
你明白会发生什么吗?调查员不会产生任何结果。这正是你问题中代码中发生的事情。
答案 3 :(得分:0)
请记住,您在C#中编写的内容不一定是完全编译的内容。 trace (Car.noOfWheels);
trace (Car.getNoOfWheels());
关键字是那些“语法糖”之一,不会产生您所写的内容。
尝试使用.Net反编译器(例如JustCode或dotPeek)打开已编译的代码,并查看IL(中介语言)结果。您将看到编译的内容不是您所期望的。
简而言之,yield
只是“创建变量,填充变量然后返回变量”的快捷方式。
您可以在此处看到更多解释:http://www.dotnetperls.com/yield