I received this feedback on the Safari site about an earlier draft of the 2nd Edition of Effective C#:
Text says: “You’ll notice that neither MyResourceHog nor DerivedResourceHog contain a finalizer. The example code I wrote does not directly contain any unmanaged resources. Therefore, a finalizer is not needed. That means the example code never calls Dispose(false). That’s the correct pattern. I take this to mean all I need is (assuming I need a finalizer):
~MyResourceHog()
{
Dispose(false);
} “Is that it? What should be done in dervied classes? Please elaborate on this just a bit more and also include the finalizer in the code, just comment it out, so we can see the full pattern for the base and dervied classes. Thanks!
I intentionally did not include an example where you included a finalizer. In the vast majority of cases, you won’t include a finalizer. If you types do not include unmanaged resources, you don’t ever need to add a finalizer. This is also explained in “Framework Design Guidelines”, pp319-322. The important reason for not including a finalizer (when you don’t need one) is that the presence of a finalizer (even if you call GC.SuppressFinalization()) affects performance. If it’s not needed, its presence is a needless performance robber.
And, if you do need a finalizer, you always need to implement IDisposable. Then, your finalizer is always as simple is shown above.
I chose not to include the expanded sample because I didn’t want to create and show a sample that would lead to a bad practice.
I create content for .NET Core. My work appears in the .NET Core documentation site. I'm primarily responsible for the section that will help you learn C#.
All of these projects are Open Source (using the Creative Commons license for content, and the MIT license for code). If you would like to contribute, visit our GitHub Repository. Or, if you have questions, comments, or ideas for improvement, please create an issue for us.