In C# when reassigning a disp开发者_运维知识库osable object variable with a new object, how does it work in the memory? Will the memory space occupied by the old object simply be overwritten by the new object? Or do I still have to call Dispose()
to release the resources it uses?
DisposableThing thing;
thing = new DisposableThing();
//....do stuff
//thing.Dispose();
thing = new DisposableThing();
In this case you have one slot / reference and two instances of an IDisposable
object. Both of these instances must be disposed indepedently. The compiler doesn't insert any magic for IDisposable
. It will simply change the instance the reference points to
A good pattern would be the following
using (thing = new DisposableThing()) {
// ... do stuff
}
thing = new DisposableThing();
Ideally the second use of thing
should also be done within a using
block
It works the same as any other assignment: =
does not care about IDisposable
or do any magic.
The object initially assigned to the variable will have to have Dispose
invoked manually (or better yet, with using
) as required. However, it may not always be correct to call Dispose
at this point: who owns the object and controls the lifetime?
Will the memory space occupied by the old object simply be overwritten by the new object?
Does not apply. Variables "name" objects. An object is itself and a variable is a variable - not the object or "location in memory". (See Eric Lippert's comment bellow: the preceding is a high-level view of variables while Eric's comment reflects variables more precisely in C# implementation, spirit, and terminology.)
Variables only affect object lifetimes insomuch as they can* keep an object from being reclaimed (and thus prevent the finalizer from [possibly eventually] running). However, variables do not control the objects semantic-lifetime -- an object may be Disposed even when not reclaimable -- or eliminate the need to invoke Dispose
as required.
Happy coding.
When dealing with disposable objects that extend beyond simple scopes -- the objects may be assigned to many different variables during their lifetime! -- I find it best to define who "takes control" which I annotate in the documentation. If the object lifetime is nicely limited to a scope then using
works well.
*A local variable itself is not necessarily sufficient to keep an object strongly reachable as it is possible that the variable/assignment is aggressively optimized out if not used later from the same scope. This may plague objects like timers.
It is possible, and common, for multiple references to the same IDisposable object to exist. There is nothing wrong with overwriting or destroying all but one of those references, provided that one reference will have Dispose called on it before it is destroyed.
Note that the purpose of IDisposable.Dispose isn't actually to destroy an object, but rather to let an object which has previously asked other entities to do something on its behalf (e.g. reserve a GDI handle, grant exclusive use of a serial port, etc.), notify those entities that they no longer need to keep doing so. If nothing tells the outside entities that they no longer need to keep doing something on behalf of the IDisposable object, they'll keep doing it--even if the object they're doing it for no longer exists.
精彩评论