You can check if an object is null but can you check if an object is valid?
Assert.IsValid(object_name);
For example, the object has been deleted by the garbage collector or someone has done dispose on it. But the pointer is still pointing to that object.
If the object has been freed by the garbage collector, you won't have a reference to it, by definition.
If it's been disposed and that's important to the object's validity, the type ought to provide a way of determining that. (In some cases Dispose can just mean "reset", for example.)
It's rarely appropriate to even allow the possibility of having a reference to a disposed object though - if you use:
using (Foo foo = new Foo())
{
...
}
then the object will be disposed at the same time that foo goes out of scope, so this isn't an issue.
If the object has been disposed, there isn't any "live" reference of it, so you can't access it (it's guaranteed that there is no reachable code that can read/write the object) (this in "safe" code... In "unsafe" code there isn't any guarantee of anything. But it's "unsafe" for a reason :-) )
For the IDisposable objects, classes "correctly done" keep a flag that they check (bool isDisposed = false at the beginning, isDisposed = true; in the Dispose()) in every method/property and if the object is already disposed they throw new ObjectDisposedException().
Note that there isn't anything in the C# language/.NET runtime that forbids for a "disposed" object to be "reignited", reused and "re-disposed" again, but it is bad code writing (and to support this "anti-pattern" there is even a GC.ReRegisterForFinalize to balance the GC.SuppressFinalize often done in Dispose())
If you have a WeakReference and you want to check "only for statistical purpose" if the object is still reachable, you use WeakReference.IsValid. If you want a reference to the object to use it, you use WeakReference.Target and check if the return value is null. This is very important!!
var wr = new WeakReference(new List<int>());
// Right!!
var target = (List<int>)wr.Target;
if (target != null)
{
target.Clear();
}
// Wrong!! The GC could kick in after the if and before the target =
if (wr.IsAlive)
{
target = (List<int>)wr.Target;
target.Clear();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With