【问题标题】:How do you dispose of IDisposableobject create inside of a Linq expression?如何在 Linq 表达式中处理 IDisposableobject create?
【发布时间】:2009-11-17 19:24:12
【问题描述】:

Linq 允许您在查询表达式中创建新对象。当您有封装列表生成的类时,这很有用。我想知道您如何处理创建的需要它的对象?

例子:

class Generator
{
    public IEnumerable<int> Gen(int size)
    {
        return Enumerable.Range(0, size);
    }
}

class bar
{
    public void doit()
    {
        var foo =
            from r in Enumerable.Range(1, 3)
            from g in new Generator().Gen(r)
            select g;
    }
}

这将创建 3 个生成器对象,这些对象将在某个时候被垃圾收集。如果 Generator 是 IDisposable,我将如何获得 Dispose() 调用?

【问题讨论】:

  • 很好的问题。我有同样的问题,只是我使用了 let 关键字。

标签: c# .net linq


【解决方案1】:

好的;我希望这是巧合,但是:SelectMany; combining IDisposable and LINQ,(使用自定义的SelectMany 实现)将允许:

    var foo =
        from r in Enumerable.Range(1, 3)
        from gen in new Generator()
        from g in gen.Gen(r)
        select g;

(请注意,我假设根据r 这样做是有合理理由的)

或使用Using() 扩展方法(而不是SelectMany):

    var foo =
        from r in Enumerable.Range(1, 3)
        from gen in new Generator().Using()
        from g in gen.Gen(r)
        select g;

【讨论】:

  • 您的博文时机恰到好处。我想在 Linq 代码中使用 DirectoryEntry 等对象,但不想让操作系统资源无人认领。
  • @Mark,是否也可以为 Select 执行此操作?我试过了,但它似乎“隐藏”了内置函数,不会让我选择任何 不是 IDisposable...
  • @Benjol - 你能提供更多信息吗?您选择的来源是什么?
  • @Mark,提出了一个问题,它几乎是重复的,所以你可能想在这里回答...stackoverflow.com/questions/3116927/…
【解决方案2】:

听起来您不应该在每次迭代时都创建一个新的 Generator 对象,原因如下:

  • 重复快速地分配(并可能释放)内存效率极低。
  • Generator 对象可能仅设计用于一个实例,以便为给定的一组参数生成值。当然,我在这方面可能是错误的,所以请在必要时澄清。

我建议您尝试以下方法:

using (var gen = new Generator())
{
    var foo =
        from r in Enumerable.Range(1, 3)
        from g in gen.Gen(r)
        select g;
}

【讨论】:

  • 是的,但这稍微回避了标题问题。
  • @Henk:确实如此,但我认为 OP 以错误的方式看待事情。 :)
  • 如果我只创建 1 个需要处理的对象,这将起作用。我承认我的示例没有显示需要,但您可以假设真正的类更复杂。通常我想在查询循环的每次迭代中创建一个新的一次性对象。
  • 很公平,在这种情况下,您可以通过 Marc 展示的扩展方法的形式获得解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-29
相关资源
最近更新 更多