In other words,
class Foo
{
object obj;
Foo() { obj = new object(); }
~Foo() { obj.ToString(); /* NullReferenceException? */ }
}
Finalizers (historically referred to as destructors) are used to perform any necessary final clean-up when a class instance is being collected by the garbage collector. In most cases, you can avoid writing a finalizer by using the System.
There are two kinds of types in C#: reference types and value types. Variables of reference types store references to their data (objects), while variables of value types directly contain their data.
A class is a reference type. Note that every array is a reference type, even if its members are value types. Since every reference type represents an underlying .
finalize provides a straight forward way to register a cleanup function to be called when an object is garbage collected. This is simpler to use than setting up a callback function on a raw weak reference, since the module automatically ensures that the finalizer remains alive until the object is collected.
It's not safe since obj might have already been garbage collected. Also note that the garbage collector will not set the reference to null. So even checking for obj != null will not help you.
See here for details: http://msdn.microsoft.com/en-us/magazine/cc163392.aspx#S3
"Generalizing this principle, in a Dispose method it’s safe to clean up all resources that an object is holding onto, whether they are managed objects or native resources. However, in a finalizer it is only safe to clean up objects that are not finalizable, and generally the finalizer should only be releasing native resources." (Your obj is finalizable, so you shouldn't touch it in another finalizer)
That's also the reason why you have the
if (disposing) {...}
in the IDisposable pattern (see Figure 2 in the link above).
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