The purpose of Dispose
is not to destroy an object, but rather to let an object inform any outside entity (or entities) that may be doing something on its behalf that it no longer needs to do so. For example, an object that encapsulates a file may ask the OS for a handle granting exclusive access to it. The OS will not allow any entity without the handle access to the file until an entity which has the handle says it's no longer needed. If the object ceased to exist without informing the OS that exclusive access was no longer needed, the OS would (probably needlessly) prevent anyone else from using the file at least until the application was closed.
The .NET Framework allows objects to request notification if they are unexpectedly abandoned, and some objects (including, btw, System.IO.File) will use such notifications to let outside entities know their services will no longer be required. Unfortunately, there's generally no guarantee as to how much time may elapse between when an object is abandoned and when (if ever) it will be notified of that. While having the system figure out eventually that e.g. a file is no longer needed may be better than having the file be held forever, having the file be closed promptly is vastly better.
Note that while one would normally think in terms of "closing" a file rather than "disposing" it, consistently using the IDisposable
interface for most kinds of objects which have asked other entities to do something on their behalf allows both VB.NET and C# to provide a using
construct e.g.
using var myFile = File.Open(whatever)
{
myFile.doStuff();
}
which will, on exit, automatically let whatever objects have started doing something on behalf of the guarded object know that they no longer need to do so (VB.NET or C# will call Dispose
on the guarded object, which will then know who needs to be notified of what). If it were necessary to Close
files, Delete
GDI objects, Release
mutexes, Shutdown
daemon services, etc. it would be hard for the language to know what a using
statement should do with its guarded object on exit. Having a single Dispose
method that does whichever of those things is appropriate greatly simplifies such constructs.