tags:

views:

208

answers:

5

What is the difference between the following two snippets of code:

using (Object o = new Object())
{
    // Do something
}

and

{
    Object o = new Object();
    // Do something
}

I have started using using a lot more but I am curious as to what the actually benefits are as compared to scoping objects.

Edit: Useful tidbits I took from this:

Jon Skeet:

Note that this does not force garbage collection in any way, shape or form. Garbage collection and prompt resource clean-up are somewhat orthogonal.

Will Eddins comment:

Unless your class implements the IDisposable interface, and has a Dispose() function, you don't use using.

+19  A: 

The first snippet calls Dispose at the end of the block - you can only do it with types which implement IDisposable, and it basically calls Dispose in a finally block, so you can use it with types which need resources cleaning up, e.g.

using (TextReader reader = File.OpenText("test.txt"))
{
    // Use reader to read the file
}
// reader will be disposed, so file handle released

Note that this does not force garbage collection in any way, shape or form. Garbage collection and prompt resource clean-up are somewhat orthogonal.

Basically, you should use a using statement for pretty much anything which implements IDisposable and which your code block is going to take responsibility for (in terms of cleanup).

Jon Skeet
Is it fair to say this this is mostly applicable when you need to clean up unmanaged resources that your class might hold? Or does it apply to purely managed classes as well?
Matt Warren
+1 for the note regarding garbage collection, I always have a tendency to forget it...
jdehaan
Ok so a typical object used to just store a structure of data would not see any benefit from the using clause but an heavier object that implements IDisposable would?
Kelsey
IDisposable/using has nothing to do with "typical" vs "heavy" objects. A class should implement IDisposable whenever it has unmanaged instance resources it needs to clear OR when it has a managed instance field that is itself IDisposable. The class could have just one field, but if that field is IDisposable then the class containing that field should also be IDisposable.
Sam
Unless your class implements the `IDisposable` interface, and has a `Dispose()` function, you don't use using. You should get a compiler error if you even try I think. This is basically a try-finally block that will guarantee your object gets disposed when out of scope.
Will Eddins
@Sam: what I ment with typical vs heavier is pretty much what you said in detail but you worded it a lot better. @Will: great comment and exactly what I was curious about the using statement.
Kelsey
@Sam: I would correct this two: "if a class has just one `IDisposable` field, _and it owns the object referenced by that field, then it should itself be `IDisposable`". Ownership is key here.
Pavel Minaev
+3  A: 

At the end of using the object gets disposed (the object you put inside the parenthesis has to implement IDisposable). The object gets disposed also in exception cases. And you do not have to wait for the GC to do it at some time (you control it).

EDIT: The disadvantage of the scoping are:

  • you do not control the disposition of the object
  • even if you would call dispose at the end of your scope, it would not be exception safe
jdehaan
+1  A: 

See the documentation regarding IDisposable and determinable resource deallocation.

Simply put, at the end of the using{} block, you can reliably dispose of allocated resources (e.g. close file handles, database connections etc.)

Brian Agnew
A: 

"using" just requires an implementation of the IDisposable interface, and calls the Dispose method at the end of the scope.

For plenty of raging arguments about properly disposing objects, there's plenty of other threads.

Mister Bee
+3  A: 

Just to literally show the difference...

using (FileStream fileStream = new FileStream("log.txt", FileMode.OpenCreate))
{
  //stuff with file stream
}

is the same as...

{
  FileStream fileStream = new FileStream("log.txt", FileMode.OpenCreate);

  try
  {
    //stuff with filestream
  }
  finally
  {
    if (fileStream != null)
      ((IDisposable)fileStream).Dispose();
  }
}

where as

{
  FileStream fileStream = new FileStream("log.txt", FileMode.OpenCreate);
  fileStream.Dispose();
}

is as it is.

Sekhat
+1 for a good example.
Kelsey