0

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?

Svish
  • 152,914
  • 173
  • 462
  • 620
Omar Kooheji
  • 54,530
  • 68
  • 182
  • 238

6 Answers6

11

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.

JYelton
  • 35,664
  • 27
  • 132
  • 191
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • If it doesn't implement IDisposable I don't think it will compile actually. – Svish Mar 17 '09 at 14:03
  • Indeed, a compilation error will occur. – Frederik Gheysels Mar 17 '09 at 14:06
  • 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 Mar 17 '09 at 14:08
  • 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 Sep 30 '09 at 13:27
  • @Svish: No. It does a null check in the finally block that the compiler generates. That's one advantage to using. – Reed Copsey Sep 30 '09 at 15:34
9
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
  • 47,787
  • 16
  • 124
  • 167
  • 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 Mar 17 '09 at 14:04
  • Added answer with correct "pretty much the same as" according to MSDN. – Svish Mar 17 '09 at 14:09
  • @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 Mar 17 '09 at 14:10
  • 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 Oct 30 '09 at 17:01
  • @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 Oct 30 '09 at 17:11
4

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
  • 56,135
  • 11
  • 101
  • 154
  • 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 Mar 17 '09 at 14:25
1

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.

Rob
  • 25,984
  • 32
  • 109
  • 155
1

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
  • 9,747
  • 2
  • 31
  • 32
1

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
  • 152,914
  • 173
  • 462
  • 620