简体   繁体   English

C#方法(收益)未检测到返回路径

[英]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迭代器是否返回任何元素,与此处无关。

Maybe this and this may also be interesting. 也许也可能很有趣。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM