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

问题描述 投票:0回答:4

请考虑下面这个非常小的方法 -:

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

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

并非所有代码路径都会返回值。

但事实并非如此 - 有人可以解释一下吗?

(.NET 4.0)

理查德

c# visual-studio yield
4个回答
3
投票

由于

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

也许thisthis也可能很有趣。


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;

0
投票

请记住,您用 C# 编写的内容不一定是经过编译的。

yield
关键字是那些“语法糖”之一,它不会产生与您所写内容完全相同的结果。

尝试使用.Net反编译器(例如JustCode或dotPeek)打开编译后的代码,并检查IL(中间语言)结果。你会发现编译出来的并不是你所期望的。

简而言之,

yield return
只是“创建变量,填充它,然后返回它”的快捷方式。

您可以在这里看到更多解释:http://www.dotnetperls.com/yield


0
投票

想想如果在以下情况下 aTestList 为空会发生什么:

IEnumerable<ObjectTest> CreateObjectList()
{
    foreach (var item in aTestList)
    {
        yield return item;
    }
}

你知道会发生什么吗?枚举器不会产生任何结果。这正是您问题中的代码中发生的情况。

© www.soinside.com 2019 - 2024. All rights reserved.