views:

362

answers:

6

I see loads of code snippets with the following Syntax

using (RandomType variable = new RandomType(1,2,3))
{
   // A bunch of code here.

}

why not just declare the variable and use it?

This Using syntax seems to just clutter the code and make it less readable. And if it's so important that that varible is only available in that scope why not just put that block in a function?

+9  A: 
using (RandomType variable = new RandomType(1,2,3))
{
   // A bunch of code here.
}

is pretty much the same (with a few subtle differences) as:

RandomType variable = new RandomType(1,2,3);

try
{
    // A bunch of code
}
finally
{
    if(variable != null)
        variable.Dispose()
}

Note that when calling "Using", you can cast anything as IDisposable:

using(RandomType as IDisposable)

The null check in the finally will catch anything that doesn't actually implement IDisposable.

Brian Genisio
Not quite: 'using' also limits the name "varialbe" to the scope of the using block, so you can re-use that name in another declaration in the same scope. But the gist is there.
Joel Coehoorn
Added answer with correct "pretty much the same as" according to MSDN.
Svish
@Joel You are right but this is enforced by the C# compiler. In IL the RandomType object is created outside the try block.@Brian Actually, the check in the finally block is if (variable != null). The C# compiler will not let you use using if RandomType does not implement IDisposable.
Jakob Christensen
adding { } around a block of code also scopes that section of code, theres no need for a using if your object isn't disposable.
Sekhat
@Sekhat: I am not suggesting that you use using() to scope the variable if it is not IDisposable. I think you misunderstood my point. I am merely explaining a sublety of the functionality that using() provides. Further, it is possible to have code where you don't know if it implements IDisposable. Wrapping it in a using() is a safe way to make it get disposed IF it implements IDisposable, but you have no way of knowing at that time. This happens often in generic methods and extension methods.
Brian Genisio
+11  A: 

Using has a very distinct purpose.

It is designed for use with types that implement IDisposable.

In your case, if RandomType implements IDisposable, it will get .Dispose()'d at the end of the block.

Reed Copsey
If it doesn't implement IDisposable I don't think it will compile actually.
Svish
Indeed, a compilation error will occur.
Frederik Gheysels
you can, however cast anything as IDisposable in using... (SomeType as IDisposable). If SomeType does not implement IDisposable, then null is passed in and never disposed, which is safe.
Brian Genisio
But if it was passed in as null, the code in the using block would most likely crash with a `NullReferenceException`, wouldn't it?
Svish
@Svish: No. It does a null check in the finally block that the compiler generates. That's one advantage to using.
Reed Copsey
+1  A: 

An object being used in a using statement must implement IDisposable, so at the end of the scope, you're guaranteed that Dispose() will be called, so theoretically, your object should be released at that point. In some cases, I've found it makes my code clearer.

unforgiven3
+4  A: 

No, it does not clutter your code , or make it less readable.

A using statement can only be used on IDisposable types (that is, types that implement IDisposable).

By using that type in a using - block, the Dispose method of that type will be used when the scope of the using-block ends.

So, tell me which code is less readable for you:

using( SomeType t = new SomeType() )
{
   // do some stuff
}

or

SomeType t = new SomeType();

try
{
   // do some stuff
}
finally
{
   if( t != null ) 
   {
      t.Dispose();
   }
}
Frederik Gheysels
Actually, both of those methods add to clutter - its just that there is currently no better option than "using". Too many using blocks (or try..finally blocks) lead to code indentation hell, and also put restrictions on where objects are created or Disposed (e.g. you can't stagger using blocks).
mbeckish
+1  A: 

The using keyword provides a deterministic way to clean up the managed or unmanaged resources that an object allocates. If you don't use the using keyword, you are responsible to call Dispose() (or in some cases, Close()) when finished with that object. Otherwise, the resources may not be cleaned up until the next garbage collection, or even not at all.

Dustin Campbell
+1  A: 

According to MSDN, the following using code:

using (Font font1 = new Font("Arial", 10.0f)) 
{
    byte charset = font1.GdiCharSet;
}

expands to this:

{
  Font font1 = new Font("Arial", 10.0f);
  try
  {
    byte charset = font1.GdiCharSet;
  }
  finally
  {
    if (font1 != null)
      ((IDisposable)font1).Dispose();
  }
}

And it does really not clutter your code. Quite the opposite actually!

Svish