Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the WinForms designer generate somewhat 'inconvenient' code in its dispose method?

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.

like image 718
Marty Avatar asked Jan 09 '12 19:01

Marty


People also ask

What does Dispose () do in C#?

The Dispose() method The Dispose method performs all object cleanup, so the garbage collector no longer needs to call the objects' Object. Finalize override. Therefore, the call to the SuppressFinalize method prevents the garbage collector from running the finalizer. If the type has no finalizer, the call to GC.

When the Dispose method is called?

It only occurs when there are objects in the Finalization Queue. It only occurs when a garbage collection occurs for Gen2 (which is approx 1 in every 100 collections for a well-written . NET app).

Is Dispose always called C#?

Dispose() will not be called automatically. If there is a finalizer it will be called automatically. Implementing IDisposable provides a way for users of your class to release resources early, instead of waiting for the garbage collector.


3 Answers

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.

like image 163
Mike Nakis Avatar answered Oct 03 '22 08:10

Mike Nakis


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.

like image 35
Roman Starkov Avatar answered Oct 03 '22 08:10

Roman Starkov


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.

like image 40
Dan Bryant Avatar answered Oct 03 '22 08:10

Dan Bryant