You're conflating the concept of disposal, which in .NET means "the implementation of IDisposable
and consequently a Dispose ()
method", and which guarantees that unmanaged resources are freed, and the concept of garbage collection, which is handled by the runtime and means "the freeing of memory allocated to objects". While you maintain a reference to any object, the garbage collector won't touch it - so the memory allocated by the object isn't freed until this happens.
These are easy concepts to confuse for two reasons:
First, its generally good practice to work with IDisposable
objects through the using
statement, as follows:
using (IDisposable d = new MyDisposableObject ()) {
// do whatever you need d for
}
which ensures that d
is disposed of when you exit the using
block; but it also restricts the scope of d
to the block, meaning that once execution exists the block, the object is also free to be garbage collected (not that it necessarily will be immediately, but thats neither here nor their since your code no longer maintains a reference to it). So in this (extremely common, and should probably be considered standard) idiom, disposal occurs at the same time as eliminating the references.
Secondly, good practice for classes that directly access unmanaged resources is to implement a finalizer that calls Dispose ()
. Finalizers run when the object is garbage collected, so you can ensure that you don't ever leave a dangling leak on an unmanaged resource, but if the object is never properly disposed of then you are leaving the decision on when to free the unmanaged resources strictly in the hands of the runtime, which decides when to perform garbage collection only on the basis of memory pressure and has no knowledge or interest in the quantity or type of references to unmanaged resources. So in this case, garbage collection of an object forces the disposal of the unmanaged resources.
In the case when you explicitly call Dispose ()
on a method, such as in your question (assuming of course that Object1
implements IDisposable
), you still maintain the reference to obj
, and as a consequence of that can access all of its properties and methods. It is of course perfectly reasonable that those methods or properties require the unmanaged resource which you have already disposed of, in which case a System.ObjectDisposedException
may be thrown, or however else the authors of Object1
have chosen to handle that case, but it also perfectly reasonable for them to function as expected if they don't require the resources you've freed.
As an example, look at System.IO.FileStream
. Once you've disposed of it, operations such as ReadByte ()
throw an exception, since theres obviously no access to the file to read from, but calling the property CanRead
just returns false
, which is valid and expected. (A MemoryStream
for example can even still access the data after a Dispose ()
call, since the (current) implementation uses a buffer managed by the runtime and not anything like a kernel handle).