Reputation: 7522
When you create a form or a user control, the WinForms designer generates a dispose method that looks like this:
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
The problem with this code is that it can lead to incorrect behaviour if it is ever edited to dispose of additional objects. I have seen .designer.cs files with dispose methods that look like this:
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
if (_myDisposable != null)
_myDisposable.Dispose();
if (_myOtherDisposable != null)
_myOtherDisposable.Dispose();
}
base.Dispose(disposing);
}
... which is incorrect, as the disposal of _myDisposable and _myOtherDisposable should not depend on whether or not components is null.
So, ignoring the argument about whether or not it is good practice to edit this designer generated code, and ignoring the fact that you can change it by editing the templates, my question is: Why doesn't the designer generate code that looks more like this?
protected override void Dispose(bool disposing)
{
if (disposing)
{
if(components != null)
components.Dispose();
}
base.Dispose(disposing);
}
This code has the same end result, but is safer and less prone to errors during modification.
Upvotes: 5
Views: 1085
Reputation: 61512
I would argue that this is because the Microsoft's "official" IDisposable
pattern tries to accomodate too many situations, unnecessarily.
For more details, see this excellent article by Stephen Cleary: [What your mother never told you about IDisposable]https://www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About). He has some great insights into the issues with IDisposable
, and how to fix them.
Stephen offers one simple guideline: just don't mix managed and unmanaged resources in a single class; instead, wrap every unmanaged resource in an IDisposable
class whose sole purpose is to dispose of the unmanaged resource.
If one follows this guideline, such arcane Dispose
methods stop being necessary, at the same time as solving a whole bunch of other, more serious issues with Microsoft's recommended pattern.
Upvotes: 3
Reputation: 273691
You're right mostly, and you didn't even mention the fact that it is placed inside the Designer.cs file.
You'll have to first move it (to MyForm.cs) and then edit it. With some common sense...
But it is largely academic, components==null will only be true on a completely empty Form. Drop 1 Button or Label and the issue doesn't come up.
I just checked, even on an empty Form it is not null
. (OK, just for Fx 4+ apparently)
Upvotes: 1
Reputation: 27515
The recommended way to handle Disposal of contained resources on a Form is to use the FormClosing or FormClosed events. UserControl has a Disposed event for the same purpose.
Upvotes: 1
Reputation: 62130
The answer is: because your convenience was not the primary concern of whoever wrote this function at Microsoft. Or perhaps they thought that you, being a non-Microsoft employee, cannot possibly be any good as a programmer, therefore, you should probably stay away from risky businesses such as modifying an object's Dispose() method.
By the way, the Dispose() method lies outside of the area within the .Designer.cs file which is designated as "do not edit this designer generated code", so I suppose it is okay to edit it.
Upvotes: 5