I'm having difficulty with C#'s 'Dispose' pattern. I have 3 classes at play here: A management class, a form, and a data-storage class.
The management class may (if it needs to) use the form to prompt the user for input. The form loads data from a file, which the user can then modify. As it is closed, the form must save this data back. The data-storage class implements .Dispose(), which does just that - writes the changes to disk.
Since this data-storage class (StoredInfo) is a member of the form (MyForm), MyForm must then also implement .Dispose() so as to call StoredInfo.Dispose. This is what is giving me issues. My management class, in it's code does:
Form.Dispose();
Form = null;
And my form:
// As written by MSVS. The exception is OK - I just want this to get called.
#region IDisposable Members
public void IDisposable.Dispose()
{
throw new NotImplementedException();
}
#endregion
...yet the Form.Dispose() method is never called. Stepping with the debugger, execution goes:
Connector.Dispose() // The management class
Form.Dispose()
Form.Dispose(bool disposing) // (1) Some method designer wrote?
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
Connector.Dispose() // Back to the management class!
Form = null;
We somehow never called .Dispose, but instead called .Dispose(bool). In C++, where arguments can have default values, I can see this, but in C#, I'm lost. My best guess is that my debugger is not showing me what is actually happening.
Now, looking at the class hierarchy, I see other classes that implement IDisposable - so there must be another Dispose() member somewhere. It's not virtual, so I'm not sure why I'm not getting compiler errors. I tried overriding the .Dispose(bool) method, since that is getting called, and is virtual, but with this:
protected override void Dispose(bool disposing)
{
StoredHosts.Dispose();
}
I get "Type 'ConnectorForm' already defines a member called 'Dispose' with the same parameter types", which, yes, I suppose it does... in Designer's code. So that's not an option. So back to calling Dispose(). But how? I'm missing the sheer simplicity and power and determinism of C++ destructors at the moment.