[.net] The using statement in C#

Started by
10 comments, last by GameDev.net 18 years, 9 months ago
Hi guys Over the last week I've been trying to pick up C#. The process of this has been quite frictionless up until now; the docs have been very useful. One thing though that I haven't figured out is about the using directive. The docs state that if I use a using directive and create instnaces within the parentheses, then the instances will be disposed of as soon as the using statement scope ends. How, exactly put, is this different from what happens when the scope of the variables would end anyway? That is what is the difference between these code blocks?
class FooClass
{
  static void Main( )
  {
    using ( FooClass foo = new FooClass( ) )
    {

      // Code that uses foo goes here

    } // What happens with foo here?
  }
}


class FooClass
{
  static void Main( )
  {
    FooClass foo = new FooClass( );

    // Code that uses foo goes here

  } // What happens with foo at this point that is different from above?
}


Thanks aforehand
Hack my projects! Oh Yeah! Use an SVN client to check them out.BlockStacker
Advertisement
The using() keyword will automatically call an IDisposable's Dispose() method at the ending brace. Despite going out of scope, the GC might not get around to collecting your object for a little while.
So it's more about when it happens than that it happens then?

Thanks for the reply.

Would there any difference between the two above blocks if I added the line
foo.Dispose( );
at the end of Main in the latter block? (Of course assuming FooClass implements IDisposable)
Hack my projects! Oh Yeah! Use an SVN client to check them out.BlockStacker
the dispose would be called at the end of the using brace regardless of exception or return within that using block.
Anything posted is personal opinion which does not in anyway reflect or represent my employer. Any code and opinion is expressed “as is” and used at your own risk – it does not constitute a legal relationship of any kind.
Yeah, paulecoyote's right. If you simply placed a call to Dispose at the end of the method, and then somewhere an exception was thrown, your call to dispose wouldn't be called.

As far as I'm aware, to ensure that Dispose gets called when YOU want it to, you either need to stick it in a finally clause, or use the using statement.
We scratch our eternal itchA twentieth century bitchWe are grateful forOur Iron Lung
using (FooClass foo = new FooClass()){  // stuff...}

is roughly equivalent to
FooClass foo = new FooClass();try{  // stuff...}finally{  foo.Dispose();}

One thing to keep in mind is that IDisposable.Dispose is simply a method, and using simply guarantees it'll be called after the using block finishes. Its purpose is to provide a way to notify the object to release unmanaged resources such as files, but it doesn't force the object to be immediately garbage-collected or anything like that.

That's the kind of info I was looking for.

Thanks.
Hack my projects! Oh Yeah! Use an SVN client to check them out.BlockStacker
The using keyword also makes more sense when you are programming in managed code. Just ask yourself: "why am I using a managed language if I intend to do manual cleanup?" That being said you can obviously do whatever you like (as long as the program works who cares, right?). It's just that the using statement is a little more "kosher" because you don't explicitly destroy an object after it's use.
I find I use it mostly when dealing with a large amount of data (through a StreamReader, for example). Don't bother using it for small things as it will just end up making your code unnecessarily messy (remember KISS) and the GC does quite a good job at cleaning up only when needed.
Rob Loach [Website] [Projects] [Contact]
Quote:Original post by Rob Loach
I find I use it mostly when dealing with a large amount of data (through a StreamReader, for example). Don't bother using it for small things as it will just end up making your code unnecessarily messy (remember KISS) and the GC does quite a good job at cleaning up only when needed.


That's a bad suggestion - you haven't understood the difference between disposing resources and having the GC free memory.

You SHOULD ALWAYS call Dispose for an IDisposable object. It has nothing with how good the GC is to do. Implementors of IDisposable are dealing with resources that needs to be released, even though the GC might not need to kick in. For instance you don't want to hold a file open longer than needed. Someone else might need to use that file for instance, but if you haven't called dispose it might in theory be opened as long as your process stays alive.

as Mutex writes, "using" is just a nice way of making sure Dispose gets called. Personally I prefer "using" syntax rather than try/finally even though it gives *exactly* the same MSIL.

This topic is closed to new replies.

Advertisement