Say I’m working with Sharepoint (this applies to other object models as well) and in the middle of my statement, I call a method, in this case ‘OpenWeb()’, which creates an IDisposable SPWeb object. Now, I cannot call Dispose() on the SPWeb object because I don’t have the reference to it. So do I need to be concerned about this leaking memory?
SPUser spUser = SPControl.GetContextSite(HttpContext.Current).OpenWeb().SiteUsers[@'foo\bar'];
I know that I could have broken up the statement into multiple lines and get the SPWeb reference to call Dispose:
SPWeb spWeb = SPControl.GetContextSite(HttpContext.Current).OpenWeb(); SPUser spUser = spWeb.SiteUsers[@'foo\bar']; spWeb.Dispose();
Please keep in mind that my question is not about aesthetics, but more about what happens to the IDisposable object that I cannot explicitly call Dispose() on, since I don’t have the reference.
Sorry about not being clear enough when I first asked the question. I’ve since rephrased it. Thanks for all the responses so far.
‘what happens to the IDisposable object that I cannot explicitly call Dispose() on?’
In general you can call Dispose (either implicitly with a using statement or explicitly) on all disposable objects, however in the hypothetical scenario where you can not, it depends on the way the object was implemented.
In general, the .Net objects will follow pattern along these lines. The pattern is to define a finalizer that cleans stuff up in case dispose is not called and then have dispose suppress the finalizer. Which reduces memory load and gives the GC less work to do.
Amongst the many problems with calling Dispose from the finalizer, is that you are turning a single threaded problem into a multithreaded problem, the finalizer will run on a different thread which can expose some very subtle and hard to catch bugs. Also, it means you will be holding on to unmanaged resources for longer than expected (Eg. you open a file, forget to call close or dispose and next time you go to open it its locked)
Bottom line is, it is a best practice to dispose all disposable objects, otherwise you can introduce weird and complex bugs. With the caveat that some frameworks, like sharepoint, return shared instances of objects that should not be disposed according to the documentation.
I usually find the code much more readable when I dispose my objects with the ‘using’ pattern. The problem with calling Dispose explicitly (object.Dispose()) is that it can be hard to trace where the object was allocated and it is very easy to forget. You can not forget to close the curly bracket of the using statement, the compiler will complain 🙂
EDIT / GOTCHA
According to MS documentation You should not call dispose on references to share point shared objects which are returned by GetContextSite. So, you should be extra careful here.
See this answer for a safe sharepoint pattern you should use.