Почему дизайнер WinForms генерирует несколько «неудобный» код в своем методе dispose? - PullRequest
5 голосов
/ 09 января 2012

Когда вы создаете форму или пользовательский элемент управления, дизайнер WinForms генерирует метод dispose, который выглядит следующим образом:

    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

Проблема с этим кодом состоит в том, что он может привести к некорректному поведению, если онкогда-либо редактировал, чтобы избавиться от дополнительных объектов.Я видел файлы .designer.cs с методами dispose, которые выглядят так:

    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);
    }

... что неверно, так как удаление _myDisposable и _myOtherDisposable не должно зависеть от того, являются ли компоненты пустыми.

Итак, игнорируя аргумент о том, является ли хорошей практикой редактировать этот код, сгенерированный дизайнером, и игнорируя тот факт, что вы можете изменить его, редактируя шаблоны, мой вопрос: почему дизайнер не делаетгенерировать код, который выглядит примерно так?

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            if(components != null)
                components.Dispose();
        }
        base.Dispose(disposing);
    }

Этот код имеет тот же конечный результат, но безопаснее и менее подвержен ошибкам во время модификации.

Ответы [ 4 ]

4 голосов
/ 09 января 2012

Ответ: потому что ваше удобство не было главной заботой того, кто написал эту функцию в Microsoft.Или, возможно, они думали, что вы, будучи сотрудником не из Microsoft, не можете быть хорошим программистом, поэтому вам, вероятно, следует избегать рискованного бизнеса, такого как изменение метода Dispose () объекта.

ByКстати, метод Dispose () находится за пределами области в файле .Designer.cs, которая обозначена как «не редактировать этот код, сгенерированный дизайнером», поэтому я полагаю, что редактировать его можно.

3 голосов
/ 09 января 2012

Я бы сказал, что это связано с тем, что «официальный» шаблон Microsoft IDisposable пытается излишне приспособиться к слишком многим ситуациям.

Подробнее см. В этой замечательной статье Стивена Клири: То, что твоя мать никогда не говорила тебе об IDisposable .У него есть отличное понимание проблем с IDisposable и способов их устранения.

Стивен предлагает одно простое руководство: просто не смешивайте управляемые и неуправляемые ресурсы в одном классе;вместо этого оберните каждый неуправляемый ресурс в класс IDisposable, единственной целью которого является избавление от неуправляемого ресурса.

Если следовать этому руководству, такие тайные методы Dispose перестают быть необходимыми, в то же время, что ирешение множества других, более серьезных проблем с рекомендованным шаблоном Microsoft.

1 голос
/ 09 января 2012

Рекомендованным способом обработки удаления содержащихся в форме ресурсов является использование событий FormClosing или FormClosed. UserControl имеет событие Disposed для той же цели.

1 голос
/ 09 января 2012

В основном вы правы, и вы даже не упомянули тот факт, что он находится внутри файла Designer.cs.

Вам нужно сначала переместить его (в MyForm.cs), а затем отредактировать. Со здравым смыслом ...

Но это в значительной степени академично, компоненты == ноль будут верны только в полностью пустой форме. Удалите 1 кнопку или ярлык, и проблема не возникнет.

Я только что проверил, даже в пустой форме это не null. (ОК, очевидно, только для Fx 4+)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...