[英]C# Method (Yield) Return Path not detected
Please consider the very small method below -: 请考虑以下非常小的方法:
IEnumerable<ObjectTest> CreateObjectList()
{
bool aTest = false;
ObjectTest anObject = null;
if (aTest == true)
{
foreach (var item in aTestList)
{
yield return anObject;
}
}
}
I feel that this code should not compile. 我觉得这段代码不应该编译。 There are paths that do not return as the boolean test fails.
由于布尔测试失败,有些路径不会返回。 The compiler should report-:
编译器应报告:
Not all code paths return a value.
并非所有代码路径都返回值。
But this isn't the case - can someone please explain? 但这不是事实-有人可以解释吗?
(.NET 4.0) (.NET 4.0)
Richard 理查德
As yield return
wil return an iterator in any case it is guaranteed to never return null
. 由于
yield return
在任何情况下都将返回迭代器,因此可以保证永远不会返回null
。 Thus a method that yields
has allways a return-value, namely the iterator. 因此,
yields
的方法始终具有返回值,即迭代器。 Wheather the iterator returns any elements or not is not relevant here. Wheather迭代器是否返回任何元素,与此处无关。
Just because you're using yield return
doesn't mean that it covers all paths through your code that are outside of the scope of the yield return
. 仅仅因为您使用的是
yield return
并不意味着它涵盖了代码中超出yield return
范围之外的所有路径。
Expanding on what HimBromBeere said in the comments, please consider this: 扩大评论中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;
}
}
That is basically what you're doing, only allowing for processing "from within" the foreach
part of you code. 这基本上就是您正在做的事情,只允许在代码的
foreach
部分中“从内部”进行处理。 That above code will throw the same error. 上面的代码将引发相同的错误。
As was said in the comments, the part that you're missing is that when your if (aTest == true)
is not valid, the rest of your code doesn't return anything. 如评论中所述,您缺少的部分是,
if (aTest == true)
无效,则其余代码将不返回任何内容。 You can maintain the code that you have above, but just include the following: 您可以维护上面的代码,但只需包括以下内容:
if (aTest == true)
{
...
}
yield break;
Think about what would happen if aTestList would be empty in the following case: 考虑以下情况下,如果aTestList为空,将会发生什么情况:
IEnumerable<ObjectTest> CreateObjectList()
{
foreach (var item in aTestList)
{
yield return item;
}
}
Do you understand what will happen? 你知道会发生什么吗? The enumerator won't yield anything.
枚举器不会产生任何结果。 That's exactly what happens in the code in your question.
这就是问题代码中发生的事情。
Remember that what you write in C# is not necessarily what is exactly compiled. 请记住,用C#编写的内容不一定完全是经过编译的。 The
yield
keyword is one of those "syntactic sugar" things that do not result in exactly what you have written. yield
关键字是那些“语法糖”的东西之一,这些东西并不会完全符合您所写的内容。
Try to open the compiled code with a .Net decompiler (JustCode or dotPeek for instance), and check out the IL (Intermediary Language) result. 尝试使用.Net反编译器(例如,JustCode或dotPeek)打开已编译的代码,然后检查IL(中间语言)结果。 You will see that what is compiled is not what you might expect.
您将看到编译后的结果不是您期望的。
In short, yield return
is just a shortcut for "create a variable, fill it, then return it". 简而言之,
yield return
只是“创建变量,填充变量,然后返回变量”的捷径。
You can see a bit more explanation here : http://www.dotnetperls.com/yield 您可以在这里看到更多解释: http : //www.dotnetperls.com/yield
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.