views:

178

answers:

3

For example,

int myResult= (new UnmanagedResourceUsingMemorySuckingPig()).GetThingsDone(id);

There is no using block, no obvious way to use a using block, no obvious way to call Dispose(). And of course UnmanagedResourceUsingMemorySuckingPig does implement IDisposable.

+8  A: 

If the finalizer of that class calls Dispose(), yes. If not, no.

(edit) Just some additional info:

Do not assume that Dispose will be called. Unmanaged resources owned by a type should also be released in a Finalize method in the event that Dispose is not called.

Edit

To clarify the above edit, I have seen many people (in this thread, on SO, and elsewhere) claim that "The GC will call Dispose() when the object is removed." This is not the case at all. Yes, a good, defensive coder writing a component will assume that Dispose() won't be called explicitly and does so in the finalizer. However, a good, defensive coder USING a component must assume that the finalizer does NOT call Dispose(). There is no automatic calling of Dispose() in the garbage collector. This functionality is ONLY in place if the finalizer calls Dispose().

Adam Robinson
Adam Robinson, I hope you agree with the edit :)
bruno conde
@bruno: Thanks! I was driving while others were posting their answers, so any help in debunking this myth that the GC automatically calls Dispose() is much appreciated!
Adam Robinson
While it's true that a Finalizer has to explicitly call Dispose, I've never seen a Disposable class with a Finalizer that doesn't call Dispose. I disagree that a user of a component should assume that a finalizer does not call Dispose - that's tantamount to assuming the component is buggy. Nevertheless I do agree that the user of a Disposable component should call Dispose (normally with the using statement).
Joe
@Joe: It's assuming that the developer didn't follow one of Microsoft's guidelines. Just as the developer must assume that Dispose() won't be called (which is a design guideline), the user must assume that he MUST call it.
Adam Robinson
Thank you for the clarification. I removed my post to end the confusion.
Chris Brandsma
+3  A: 

I don't believe so. You'll have to write:

 using (UnmanagedResourceUsingMemorySuckingPig urumsp = new UnmanagedResourceUsingMemorySuckingPig()) 
{
  myResult= urumsp.GetThingsDone(id);
}
Otávio Décio
A: 

No. However, the GC will eventually collect the object and notice that it is finalizable (it is finalizable, right?) and will finalize it for you. Dispose is for deterministically cleaning up resources.

HTH, Kent

Kent Boogaart
Mostly yes, but: this may be too late (e.g. if your code wants to use the unmanaged resource before the GC collects it), and doesn't always work - e.g. http://msdn.microsoft.com/en-us/library/system.directoryservices.searchresultcollection.aspx "Due to implementation restrictions, the SearchResultCollection class cannot release all of its unmanaged resources when it is garbage collected. "
Joe
This is incorrect, just as the other answer is. There is no facility in the GC for calling dispose. If the finalizer does so (which you have to code explicitly), then this is true. If the finalizer does not (which it won't if you don't tell it to), then this is not true.
Adam Robinson
@Adam: I didn't say the GC called Dispose, I said it finalized the object.
Kent Boogaart
The implication was that this would, in turn, call Dispose(), was it not? If so, then it is not necessarily true. If not, then what does this have to do with the question...?
Adam Robinson
No, that was certainly not the implication. I'm not sure how you read it that way. It specifically says "no" and "dispose is for deterministically cleaning up resources". GC is not deterministic.
Kent Boogaart
If you were not meaning to imply that the GC would call Dispose(), what bearing does this have on the question, then?
Adam Robinson
@Adam: To clarify the difference between deterministic and non-deterministic cleanup. Very pertinent to the question, if you ask me.
Kent Boogaart
But GC cleanup has nothing to do with calling dispose. In fact, there is NO deterministic cleanup of managed resources in .NET. Even invoking the GC manually is not a 100% guarantee that your resources are being cleaned up synchronously. using() blocks deal only with objects that implement IDisposable, which are designed to deal with unmanaged resources. The point of is it not to provide "deterministic" cleanup (though I'm not sure that's really the term you're looking for) of anything.
Adam Robinson
I don't know how you're reading into my response what you're reading. At no point did I claim GC is deterministic, nor did I claim that GC invokes the Dispose() method. What I'm saying is that a using statement *is* deterministic because it is guaranteed to invoke Dispose() when the block exits. Anyway, I've had enough arguing this for one night. Cheers.
Kent Boogaart