views:

214

answers:

6

I see this:

using (StreamWriter sw = new StreamWriter("file.txt"))
{
     // d0 w0rk s0n
}

Everything I try to find info on is does not explain what this doing, and instead gives me stuff about namespaces.

+12  A: 

You want to check out documentation for the using statement (instead of the using directive which is about namespaces).

Basically it means that the block is transformed into a try/finally block, and sw.Dispose() gets called in the finally block (with a suitable nullity check).

You can use a using statement wherever you deal with a type implementing IDisposable - and usually you should use it for any disposable object you take responsibility for.

A few interesting bits about the syntax:

  • You can acquire multiple resources in one statement:

    using (Stream input = File.OpenRead("input.txt"),
           output = File.OpenWrite("output.txt"))
    {
        // Stuff
    }
    
  • You don't have to assign to a variable:

    // For some suitable type returning a lock token etc
    using (padlock.Acquire())
    {
        // Stuff
    }
    
  • You can nest them without braces; handy for avoiding indentation

    using (TextReader reader = File.OpenText("input.txt"))
    using (TextWriter writer = File.CreateText("output.txt"))
    {
        // Stuff
    }
    
Jon Skeet
Why would I want to dispose instead of being lazy? Is it like uber garbage collection?
Joshua
@Joshua: To clean up after yourself - you don't want to leave open file handles for example.
Jon Skeet
Why don't they auto-close at the end of the scope in the destructor?
Joshua
Like how do I know which kinda objects to use this on? Any object??
Joshua
@Joshua: the scope defines the minimum lifetime, not the maximum lifetime. It's a garbage-collected language; the collector can run any time it feels like.
Eric Lippert
@Joshua: Because C# doesn't have deterministic finalization. Are you a C++ developer? It's worth being *very* clear about the difference between native C++ object lifetimes and those in .NET - where the garbage collector may well wait a while before collecting objects.
Jon Skeet
@Joshua: As for which objects - you *can* use it with anything that implements `IDisposable`. You *should* almost always use it for objects which your code "owns" (typically by creating it) which implement `IDisposable`.
Jon Skeet
Yes I come from C++ where cleaning after yourself is a MUST and EVERYWHERE. I guess what you're telling me is here in C# seems it is ONLY in SOME places.... I just need like a list of those places!
Joshua
Anything implementing `IDisposable` would qualify as one of those places ;)
Nate Bross
@Nate - not quite... See http://blogs.msdn.com/kimhamil/archive/2008/11/05/when-to-call-dispose.aspx for a good summary.
kvb
@kvb: I don't think those are good guidelines. Better: if you create it, and use it entirely within the scope of a method, and it implements `IDisposable`, and if it's not a WCF proxy instance, then `Dispose` it. You may get away with not disposing `DataSet` and such things that only implement `IDisposable` because they inherit `Component`, and Mr. Richter may be right about Pens and Fonts, but anything else is taking too many chances. You need to ask, "why not"?
John Saunders
@John - you can certainly quibble with the specific guidelines. I just wanted to highlight that it's not as simple as "Call Dispose on anything implementing IDisposable". Unfortunately, there are a significant number of subtleties.
kvb
@kvb: I believe there's only one "subtlety" that's actually harmful in general, that's the WCF proxies. All the others I've read about are, at worst, a waste of time. In general, I'd rather give out a blanket statement and have the resources cleaned up, rather than the opposite.
John Saunders
+10  A: 

The using construct is essentially a syntactic wrapper around automatically calling dispose on the object within the using. For example your above code roughly translates into the following

StreamWriter sw = new StreamWriter("file.text");
try {
  // do work 
} finally {
  if ( sw != null ) {
    sw.Dispose();
  }
}
JaredPar
+2  A: 

Here you go: http://msdn.microsoft.com/en-us/library/yh598w02.aspx

Basically, it automatically calls the Dispose member of an IDisposable interface at the end of the using scope.

John Fisher
+5  A: 

Your question is answered by section 8.13 of the specification.

Eric Lippert
C# 3 specification: http://download.microsoft.com/download/3/8/8/388e7205-bc10-4226-b2a8-75351c669b09/CSharp%20Language%20Specification.doc
Jon Skeet
Haha. I was about to downvote for an unhelpful answer, but then I noticed who it was. I suppose you're allowed to get away with answers like that.
Simon P Stevens
@Simon: There simply is no substitute for reading the specification. That's what *I* do when I have a question about the language.
Eric Lippert
A: 

check this Using statement

Hun1Ahpu
@Hun1Ahpu: please try to give out only current references to MSDN. I fixed your link.
John Saunders
A: 

It scopes the object(s) created at the beginning of the 'using' statement - Dispose() is automatically called when the block terminates. The object(s) must be convertible to IDisposable.

Alex