C#:foreach中的yield return失败 - body不能成为迭代器块

p.c*_*ell 42 c# iterator yield

考虑一下混淆代码.目的是通过匿名构造函数及其动态创建一个新对象yield return.目标是避免仅仅为了维护本地集合return.

public static List<DesktopComputer> BuildComputerAssets()
{           
    List<string> idTags = GetComputerIdTags();

    foreach (var pcTag in idTags)
    {
        yield return new DesktopComputer() {AssetTag= pcTag
                                          , Description = "PC " + pcTag
                                          , AcquireDate = DateTime.Now
                                           };
    }            
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这段代码会产生异常:

错误28'Foo.BuildComputerAssets()'的主体不能是迭代器块,因为'System.Collections.Generic.List'不是迭代器接口类型

问题

  • 这个错误信息是什么意思?
  • 如何避免此错误并yield return正确使用?

SLa*_*aks 53

您只能yield return在返回an IEnumerable或an 的函数中使用IEnumerator,而不是a List<T>.

你需要改变你的功能才能返回IEnumerable<DesktopComputer>.

或者,您可以重写要使用的函数List<T>.ConvertAll:

return GetComputerIdTags().ConvertAll(pcTag => 
    new DesktopComputer() {
        AssetTag    = pcTag,
        Description = "PC " + pcTag,
        AcquireDate = DateTime.Now
    });
Run Code Online (Sandbox Code Playgroud)


Bri*_*sio 17

您的方法签名是错误的.它应该是:

public static IEnumerable<DesktopComputer> BuildComputerAssets()
Run Code Online (Sandbox Code Playgroud)


Mic*_*tum 8

yield仅适用于Iterator类型:

yield语句只能出现在迭代器块中

迭代器定义为

迭代器的返回类型必须是IEnumerable,IEnumerator,IEnumerable <T>或IEnumerator <T>.

IList和IList <T>确实实现了IEnumerable/IEnumerable <T>,但是枚举器的每个调用者都需要上面四种类型中的一种,而不是其他类型.