Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you dispose of IDisposableobject create inside of a Linq expression?

Tags:

c#

.net

linq

Linq allows you to create new object inside of a query expression. This is useful when you have classes that encapsulate generation of a list. I’m wondering how you dispose of objects that are created that need it?

Example:

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;
    }
}

This will create 3 Generator objects that will be garbage collected at some point. If Generator was IDisposable how would I get the Dispose() call?

like image 964
Jason Avatar asked Nov 17 '09 19:11

Jason


2 Answers

OK; I'm hoping this is coincidence, but: SelectMany; combining IDisposable and LINQ, which (with the custom SelectMany implementation) would allow:

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

(note that I'm assuming there is a sensible reason to do this per r)

SelectMany

or with the Using() extension method (instead of SelectMany):

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

Using

like image 191
Marc Gravell Avatar answered Oct 21 '22 21:10

Marc Gravell


Doesn't sound like you should be creating a new Generator object on each iteration, for a couple of reasons:

  • It's horribly inefficient to allocate (and potentially deallocated) memory repeatedly and rapidly.
  • The Generator object is probably designed for only one instance to generate values for a given set of parameters. Of course, I may be wrong on this, so please clarify if necessary.

I recommend you try the following:

using (var gen = new Generator())
{
    var foo =
        from r in Enumerable.Range(1, 3)
        from g in gen.Gen(r)
        select g;
}
like image 39
Noldorin Avatar answered Oct 21 '22 21:10

Noldorin