IEnumerable comprehension vs返回Collection Type

时间:2012-01-26 02:57:17

标签: c# list-comprehension

以下是否有任何情况:

public IEnumerable<Foo> Foobar (Bar bar)
{
    List<Foo> result = new List<Foo>()
    foreach(var Qux in bar.QuxSource)
    {
        Foo item;
        ... //a procudure that is intricate enough not to be clearly repressentable with a LINQ method
        result.Add(item);
        ... //The aforementioned inticate proceduce continues. Possiblily adding more items to result
    }
    return result;
}

更可取:

public IEnumerable<Foo> Foobar (Bar bar)
{
    foreach(var Qux in bar.QuxSource)
    {
        Foo item;
        ... //a procudure that is intricate enough not to be clearly repressentable with a LINQ method
        yield return item;
        ... //The aforementioned inticate proceduce continues. Possiblily yielding more items
    }
}

我的意思是后者显然很精彩。 随着deferred操作的荣耀,如果我只使用Foobar(someBar).First(),它不需要生成所有返回的项目。

我看到前者使用了很多,特别是经验丰富的编码员。 (我猜想现代C#中的列表补偿并不是最新的)。 前patern更好的下层问题是什么? (仅查看​​库代码,目标是重用) 我想也许当能够生产项目依赖于某些外部资源,例如打开文件。 foreach的用例是什么? 我猜是

2 个答案:

答案 0 :(得分:3)

您的示例用例是正确的,但更一般地说,您可能希望采用以前的模式:

  • 源使用稀缺资源,您需要保证枚举器将被处置(如果您要开始枚举后一种方法并在中间停止而不处置枚举器,它将保持打开状态)< / LI>
  • 应尽快列举来源
  • 您必须保证评估整个来源

答案 1 :(得分:2)

第一种方法 - 急切地枚举源序列 - 在访问源序列的时间有限或者应该限制在一个狭窄的时间窗口时是首选 - 也就是说,当使用Linq从数据库检索数据时就是这种情况。 SQL或Linq to Entities提供程序。在第二种方法中,您依赖于消费者来枚举您的源,这可能需要更长的时间 - 通常您不希望长时间保持数据库连接打开。