views:

2327

answers:

21

User kokos answered the wonderful Hidden Features of C# question by mentioning the using keyword. Can you elaborate on that? What are good uses of using?

+2  A: 

When using ADO.NET you can use the keywork for things like your connection object or reader object. That way when the code block completes it will automatically dispose of your connection.

Joseph Daigle
I would just add that the code block doesn't even have to complete. A using block will dispose of the resource even in the event of an unhandled exception.
harpo
Just to further clarify, it's a way of making sure the Garbage Collector takes care of your allocations when you want it to, instead of doing it when *it* wants to.
mos
+7  A: 

Things like this:

using conn As New SqlConnection("connection string")
{
   conn.Open()

    // execute sql statement here on the connection you created
}

This SqlConnection will be closed even if an exception is thrown, without the need for a try/catch/finally.

Joel Coehoorn
+1  A: 

RhinoMocks makes an intersting use for using.

Gilligan
its basically the same as calling Playback and Verify all it just does that in the Dispose() methods
George Mauer
A: 

Thanks to the comments below, I will clean this post up a bit (I shouldn't have used the words 'garbage collection' at the time, apologies):
When you use using, it will call the Dispose() method on the object at the end of the using's scope. So you can have quite a bit of great cleanup code in your Dispose() method.
A bullet point here which will hopefully maybe get this un-markeddown: If you implement IDisposable, make sure you call GC.SuppressFinalize() in your Dispose() implementation, as otherwise automatic garbage collection will try to come along and Finalize it at some point, which at the least would be a waste of resources if you've already Dispose()d of it.

Grank
It has no effect on the GC.
Jason Diller
It has an indirect effect. Because you've disposed of the object explicitly, it does not require finalization and can therefore be GC'd earlier.
Kent Boogaart
+17  A: 

using can be used to call IDisposable. It can also be used to alias types.

using (SqlConnection cnn = new SqlConnection()) { /*code*/}
using f1 = System.Windows.Forms.Form;
MagicKat
+1  A: 

"using" can also be used to resolve name space conflicts. See http://www.davidarno.org/c-howtos/aliases-overcoming-name-conflicts/ for a short tutorial I wrote on the subject.

David Arno
A: 

The using keyword defines the scope for the object and then disposes of the object when the scope is complete. For example.

using (Font font2 = new Font("Arial", 10.0f))
{
    // use font2
}

See here for the MSDN article on the C# using keyword.

David Basarab
A: 

using is used when you have a resource that you want disposed after it's been used.

For instance if you allocate a File resource and only need to use it in one section of code for a little reading or writing, using is helpful for disposing of the File resource as soon as your done.

The resource being used needs to implement IDisposable to work properly.

Example:

using (File file = new File (parameters))
{
    *code to do stuff with the file*
}
Bob
+18  A: 

The reason for the "using" statement is to ensure that the object is always disposed correctly, and it doesn't require explicit code to ensure that this happens.

As per http://www.codeproject.com/KB/cs/tinguusingstatement.aspx, the .NET CLR converts

using (MyResource myRes = new MyResource())
{
    myRes.DoSomething();
}

to

MyResource myRes= new MyResource();
try
{
    myRes.DoSomething();
}
finally
{
    // Check for a null resource.
    if (myRes!= null)
        // Call the object's Dispose method.
        ((IDisposable)myRes).Dispose();
}
paulwhit
Thanks! I was never completely clear about the 'using' statement. Very helpful!
Sam Wessel
+1  A: 

Interestingly, you can also use the using/IDisposable pattern for other interesting things (such as the other point of the way that Rhino Mocks uses it). Basically, you can take advantage of the fact that the compiler will always call .Dispose on the "used" object. If you have something that needs to happen after a certain operation ... something that has a definite start and end ... then you can simply make an IDisposable class that starts the operation in the constructor, and then finishes in the Dispose method.

This allows you to use the really nice using syntax to denote the explicit start and end of said operation. This is also how the System.Transactions stuff works.

Joel Martinez
+1  A: 

I've used it a lot in the past to work with input and output streams. You can nest them nicely and it takes away a lot of the potential problems you usually run into (by automatically calling dispose). For example:

        using (FileStream fs = new FileStream("c:\file.txt", FileMode.Open))
        {
            using (BufferedStream bs = new BufferedStream(fs))
            {
                using (System.IO.StreamReader sr = new StreamReader(bs))
                {
                    string output = sr.ReadToEnd();
                }
            }
        }
Sam Schutte
+2  A: 

It's a C# way of supporting the RAII idiom: http://www.hackcraft.net/raii/

Nemanja Trifunovic
+4  A: 

Stupid answer but since no one has said it yet:

using MyNamespace.Yippie;
George Mauer
A: 

Not that it is ultra important, but using can also be used to change resources on the fly. Yes disposable as mentioned earlier, but perhaps specifically you don't want the resources they mismatch with other resources during the rest of your execution. So you want to dispose of it so it doesn't interfere elsewhere.

+10  A: 

Since a lot of people still don't know that you can do:

using (System.IO.StreamReader r = new System.IO.StreamReader(""))
using (System.IO.StreamReader r2 = new System.IO.StreamReader("") {
   //code
}

I guess a lot of people still don't know that you can do:

using (System.IO.StreamReader r = new System.IO.StreamReader(""), r2 = new System.IO.StreamReader("")) {
   //code
}
BlackTigerX
+1  A: 

I am using this alot:

||
\/

A simpler transaction scope

Drakiula
A: 

In conclusion, when you use a local variable of a type that implements IDisposable, always, without exception, use using1.

If you use nonlocal IDisposable variables, then always implement the IDisposable pattern.

Two simple rules, no exception1. Preventing resource leaks otherwise is a real pain in the *ss.


1): The only exception is – when you're handling exceptions. It might then be less code to call Dispose explicitly in the finally block.

Konrad Rudolph
A: 

Another example of a reasonable use in which the object is immediately disposed:

using (IDataReader myReader = DataFunctions.ExecuteReader(CommandType.Text, sql.ToString(), dp.Parameters, myConnectionString)) 
{
    while (myReader.Read()) 
    {
        MyObject theObject = new MyObject();
        theObject.PublicProperty = myReader.GetString(0);
        myCollection.Add(theObject);
    }
}
Brendan Kendrick
A: 

Another great use of using is when instantiating a modal dialog.

Using frm as new Form1

Form1.ShowDialog

' do stuff here"

End Using"

Lucas
+3  A: 

using, in the sense of

using (var foo = new Bar())
{
  Baz();
}

Is actually shorthand for a try/finally block. It is equivalent to the code:

var foo = new Bar();
try
{
  Baz();
}
finally
{
  foo.Dispose();
}

You'll note, of course, that the first snippet is much more concise than the second and also that there are many kinds of things that you might want to do as cleanup even if an exception is thrown. Because of this, we've come up with a class that we call Scope that allows you to execute arbitrary code in the Dispose method. So, for example, if you had a property called IsWorking that you always wanted to set to false after trying to perform an operation, you'd do it like this:

using (new Scope(() => IsWorking = false))
{
  IsWorking = true;
  MundaneYetDangerousWork();
}

You can read more about our solution and how we derived it here.

David Mitchell
A: 

Everything outside the curly brackets is disposed, so it is great to dispose your objects if you are not using them. This is so because if you have a SqlDataAdapter object and you are using it only once in the application life cycle and you are filling just one dataset and you don't need it anymore, you can use the code:

using(SqlDataAdapter adapter_object = new SqlDataAdapter(sql_command_parameter))
{
   // do stuff
} // here adapter_object is disposed automatically
milot