Deriving from a component and implementing IDisposable properly
c#, c#-2.0, components, idisposable
Solution
`SomeDisposableComponentBase` should override `Component.Dispose(Boolean)`.
You also need to delete the `SomeDisposableComponentBase.Dispose()` method (that takes no arguments), because it hides the `Component.Dispose` implementation, so they're treated as different methods, depending on how you declare your variables:
using (Component component = new SomeDisposableComponent()) {
// Calls Component.Dispose upon exiting the using block
}
using (SomeDisposableComponentBase component = new SomeDisposableComponent()) {
// Calls SomeDisposableComponentBase.Dispose upon existing the using block
}
Problem
I have a Visual Studio 2008 C# .NET 2.0 CF project with an abstract class derived from Component. From that class, I derive several concrete classes (as in my example below). But, when I go to exit my Form, though the Form's Dispose() member is called and components.Dispose() is called, my components are never disposed. Can anybody suggest how I can fix this design? ``` public abstract class SomeDisposableComponentBase : Component { private System.ComponentModel.IContainer components; protected SomeDisposableComponentBase() { Initializecomponent(); } protected SomeDisposableComponentBase(IContainer container) { container.Add(this); Initializecomponent(); } private void InitializeComponent() { components = new System.ComponentModel.Container(); } protected abstract void Foo(); #region IDisposable Members bool disposed_; /// Warning 60 CA1063 : Microsoft.Design : Ensure that 'SomeDisposableComponentBase.Dispose()' is declared as public and sealed.* public void Dispose() { // never called Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { // never called if (!disposed_) { if (disposing && (components != null)) { components.Dispose(); } disposed_ = true; } base.Dispose(disposing); } #endregion } public SomeDisposableComponent : SomeDisposableComponentBase { public SomeDisposableComponent() : base() { } public SomeDisposableComponent(IContainer container) : base(container) { } protected override void Foo() { // Do something... } protected override void Dispose(bool disposing) { // never called base.Dispose(disposing); } } public partial class my_form : Form { private SomeDisposableComponentBase d_; public my_form() { InitializeComponent(); if (null == components) components = new System.ComponentModel.Container(); d_ = new SomeDisposableComponent(components); } /// exit button clicked private void Exit_Click(object sender, EventArgs e) { this.Close(); } /// from the my_form.designer.cs protected override void Dispose(bool disposing) { if (disposing && (components != null)) { // this function is executed as expected when the form is closed components.Dispose(); } base.Dispose(disposing); } } ``` *I note that FX-Cop is giving me a hint here. But, if I try to declare that function as sealed, I get the error: ``` error CS0238: 'SomeDisposableComponentBase.Dispose()' cannot be sealed because it is not an override ``` Declaring that function an override leads to: ``` 'SomeDisposableComponentBase.Dispose()': cannot override inherited member 'System.ComponentModel.Component.Dispose()' because it is not marked virtual, abstract, or override ``` Thanks, PaulH