Search code examples
c#destructordispose

c# destructors: the dispose "pattern" and best practises


I know the difference in meaning and use of destructors and finalisers in c#.

However, typically the answer to a "should I ..." is answered by "don't use destructors, rather use the dispose pattern as shown in MSDN". Eric Lippert writes quite strongly against using destructors unnecessarily.

But, that "pattern" advocates writing a destructor as such ~T() { Dispose(false); }. The stated reason is that it is a "fallback" which is called in case the programmer forgets to call Dispose(). Of course this ignores the fact that finalisers are indeterminate in their operation, and may never even run.

Hence:

  1. If I use the dispose pattern, should I also provide the destructor? Incidentally, I am only disposing managed resources (the Entity Framework DataContext for example).

  2. If I do provide a destructor: if my class is derived from an IDisposable, which may already provide a destructor, then should I provide one too? I thought that one never writes a destructor in such a case, however docs say that it will call the base class' destructor automatically anyway.


Solution

  • If I use the dispose pattern, should I also provide the destructor? Incidentally, I am only disposing managed resources (the Entity Framework DataContext for example).

    In this case, no. The reason is that, by the time your class is caught by the GC, all of those objects are also going to be handled by the GC. There is no reason to add the overhead of a destructor in this case.

    This is part of the complexity of IDisposable - there really should be more than the standard implementation, depending on the usage. In this case, you're encapsulating a resource that implements IDisposable. As such, its important to allow your user to (indirectly) dispose those resources, but you don't need to handle the destructor, as there is no unmanaged resource you directly "own". I cover this in Part 3 of my series on IDisposable if you want more details.


    if I do provide a destructor: if my class is derived from an IDisposable, which may already provide a destructor, then should I provide one too? I thought that one never writes a destructor in such a case, however docs say that it will call the base class' destructor automatically anyway.

    In this case, the base class should expose a protected method of the form protected virtual void Dispose(bool disposing). You would put your resource cleanup logic there, as the base class destructor handles the call to this method for you. For details, see Part 2 of my series on IDisposable.