【问题标题】:Can you yield return into an IList<T>?您可以将收益返回到 IList<T> 吗?
【发布时间】:2010-03-05 19:04:42
【问题描述】:

在我的 MVC 应用程序的服务层中,我试图将 linq 到 sql 实体结果转换为我的业务模型实体。我目前正在尝试以下代码:

    public IList<Project> GetAllProjects()
    {
        var results = from p in _context.Repository<DBMappings.project>()
                      select p;

        foreach (DBMappings.project prj in results.ToList<DBMappings.project>())
            yield return CreateProjectEntityFromDBProject(prj);

    }

不幸的是,这似乎不起作用,我唯一能猜到的是 yield 仅适用于 IEnumerable。除了创建新列表、在 foreach 循环中添加项目并返回列表之外,还有其他解决方案吗?我需要使用 IList,因为使用返回列表的方法需要能够执行 List 方法,例如 .Sort()。

【问题讨论】:

    标签: .net c#-3.0 yield-return


    【解决方案1】:

    如果你想.Sort(),你绝对应该在你的方法中创建一个列表。使用 yield 可以节省一些内存 - 因为结果不会存储为单个对象。当您只想浏览结果时,这很有用。但是,如果您想对某些内容进行排序,则需要将其作为一个整体存储在内存中。

    【讨论】:

    • 让我给你一些关于产量的常见建议。当您确定它对当前任务有用时使用它。如果您怀疑,请不要使用它。 :)
    【解决方案2】:

    C# 规范的第 8.14 节(重点是我的):

    yield 语句用于 迭代器块(§8.2)产生一个值 枚举器对象(§10.14.4)或 的可枚举对象(§10.14.5) 迭代器或发出结束信号 迭代。

    IList 实现了 IEnumerable,但它没有实现 IEnumerator。

    【讨论】:

    • 啊,这解释了我的部分困惑。我没有意识到有一个 IEnumerator,我以为它只是 IEnumable
    【解决方案3】:

    你不能“懒惰地返回”一个列表,但似乎你可以得到你想要的:

    return results.Select(prj=>CreateProjectEntityFromDBProject(prj)).ToList();
    

    或者只是

    var results = from p in _context.Repository<DBMappings.project>()
                      select CreateProjectEntityFromDBProject(p);
    return results.ToList();
    

    【讨论】:

    • 感谢 Linq 与普通 C# 的不同之处,很容易忘记它仍然是 C#...
    【解决方案4】:

    IList&lt;T&gt; 描述了与 IEnumerable&lt;T&gt; 不兼容的功能,至少就延迟加载而言。

    能够转到特定索引(例如 IList&lt;T&gt;),需要“枚举”整个枚举,至少到指定索引为止。

    如果你不关心整个IEnumerable&lt;T&gt;的求值,那么你可以构造一个List&lt;T&gt;,将IEnumerable&lt;T&gt;作为构造函数参数,然后将List&lt;T&gt;作为IList&lt;T&gt;返回

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-27
      • 2013-05-31
      • 1970-01-01
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多