If a C# derived IDisposable class constructor generates an error, how to dispose of the already fully constructed IDisposable base class?
Since all fields in the class hierarchy are initialized before any constructor executes, is it safe for the derived constructor to call base.Dispose()? It violates the rule of not calling virtual methods until object is fully constructed, but I can't think of another way to do it, and my searching hasn't turned up anything about this scenario.
The Dispose method performs all object cleanup, so the garbage collector no longer needs to call the objects' Object. Finalize override. Therefore, the call to the SuppressFinalize method prevents the garbage collector from running the finalizer. If the type has no finalizer, the call to GC.
Dispose() will not be called automatically. If there is a finalizer it will be called automatically. Implementing IDisposable provides a way for users of your class to release resources early, instead of waiting for the garbage collector.
To free and reset the resources that are unmanaged like connections to the databases, files, etc., and to perform a cleanup of the memory, we make use of a function called dispose of () function in C#. The dispose() function in C# must implement the IDisposable interface.
As an example, consider a class that holds a database connection instance. A developer can call Dispose on an instance of this class to release the memory resource held by the database connection object. After it is freed, the Finalize method can be called when the class instance needs to be released from the memory.
My view is that constructors should be light, not relying on external resources/etc that might throw an exception. The constructor should do enough to verify Dispose() can be safely called. Consider using containment instead of inheritance, or having a factory method do the work that might throw.
All derived class constructors must call Dispose
on the object being constructed if they exit via an exception. Further, it's very difficult to write leak-proof classes if field initializers construct IDisposable
instances or can fail. Too bad, since requiring objects to be declared in one place, initialized in a second, and cleaned up in a third is not exactly a recipe for coherent code.
I would suggest that the best pattern is probably something like:
class foo : baseFoo , IDisposable
{
foo () : baseFoo
{
bool ok = false;
try
{
do_stuff();
ok = true; // Only after last thing that can cause failure
}
finally
{
if (!ok)
Dispose();
}
}
}
Note that C++/CLI automatically implements that pattern, and can also automatically handle cleanup of IDisposable fields. Too bad the language seems like a pain in other ways.
PS--With relatively few exceptions, mostly revolving around predictable-cost shared immutable objects (e.g. brushes, fonts, small bitmaps, etc.), code which relies upon Finalize
to clean up objects is broken. If an IDisposable
is created, it must be disposed unless the code which created it has particular knowledge about the consequences of deferring disposal to a finalizer.
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