未检测到c#方法(Yield)返回路径

本文关键字:Yield 返回路径 方法 检测 | 更新日期: 2023-09-27 18:05:38

请考虑下面这个很小的方法:

IEnumerable<ObjectTest> CreateObjectList()
{
    bool aTest = false;
    ObjectTest anObject = null;
    if (aTest == true)
    {
        foreach (var item in aTestList)
        {
            yield return anObject;
        }
    }
}

我觉得这段代码不应该编译。当布尔测试失败时,有些路径不会返回。编译器应该报告-:

不是所有的代码路径都返回值。

但事实并非如此——有人能解释一下吗?

(。NET 4.0)

理查德

未检测到c#方法(Yield)返回路径

由于yield return在任何情况下都会返回一个迭代器,因此保证永远不会返回null。因此,yields总是有一个返回值的方法,即迭代器。迭代器是否返回任何元素与此无关。

也许这个和这个也会很有趣

仅仅因为您使用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;
    }
}

你知道会发生什么吗?枚举数不会产生任何结果。