В шаблоне IDisposable базовый класс должен позволить производным классам совместно использовать свой склонный флаг?

Принятый ответ правильный, но если вы хотите избежать ввода пароля в интерактивном режиме, вы можете использовать это:

PGPASSWORD={{export_db_password}} pg_dump --create -h {{export_db_host}} -U {{export_db_user}} {{export_db_name}} | PGPASSWORD={{import_db_password}} psql -h {{import_db_host}} -U {{import_db_user}} {{import_db_name}}
5
задан morechilli 3 July 2009 в 16:02
поделиться

4 ответа

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

Например, рассмотрим сценарий, в котором у вас есть свойство Disposed только для чтения в базовом классе. Поле поддержки имеет значение true только в методе Dispose (уничтожение) базового класса. Это означает, что свойство Disposed может когда-либо возвращать истину только в том случае, если вызывается базовый класс Dispose (конечно, за исключением злого отражения). Это позволяет базовому классу предоставлять принудительный контракт.

Теперь рассмотрим противоположное, где есть защищенный установщик. Теперь любой класс может произвольно установить для свойства Disposed значение true, ничего не удаляя. Это создает возможность для Dispose вернуть true, когда ничего не удалено.

Я бы выбрал первый вариант, потому что он обеспечивает наиболее юридически исполнимый контракт.

5
ответ дан 14 December 2019 в 19:22
поделиться

В дополнение к ответу JaredPar я бы добавил, что не всегда обязательно наличие флага _disposed . Очень часто другие «связанные с ресурсами» поля объекта естественным образом обеспечивают способ представления удаленного состояния.

Например, внешний COM-объект, который должен быть Завершено , прежде чем он будет удален, будет будет представлена ​​ссылкой на COM-объект, и поэтому соответствующая часть Dispose будет выглядеть так:

if (_comObject != null)
{
    _comObject.Shutdown();
    _comObject = null;
}

Это можно безопасно запустить несколько раз, не вызывая более одного раза Shutdown , поскольку необходимо. Другие методы, которые пытаются использовать _comObject после Dispose , получат NullReferenceException , или, в идеале, эти методы должны были бы проверять поле _comObject и генерировать исключение ObjectDisposedException .

Я считаю, что это чаще всего правда, чем нет - часто реализовав IDisposable, я не припомню, чтобы когда-либо понадобился отдельный _disposed поле. Введение одного из них увеличило бы степень свободы (увеличило бы количество способов, которыми я могу облажаться).

Так что вряд ли это будет так полезно для производных классов, даже если это была безопасная идея (а это не так, как объясняет ДжаредПар)

0
ответ дан 14 December 2019 в 19:22
поделиться

Я бы рекомендовал иметь свойство Disposed в базовом классе с общедоступным геттером и защищенным сеттером.

0
ответ дан 14 December 2019 в 19:22
поделиться

В случае, если у вас есть методы, которые должны делать что-то другое после удаления класса, например, генерировать исключение, я бы создал защищенное свойство только получения для базового класса, которое считывает частные поле базового класса. Таким образом, вы позволяете любому наследнику узнать, может ли он выполнить операцию.

Затем, чтобы узнать, был ли класс уже размещен в его собственном методе удаления (например: чтобы избежать освобождения ресурсов дважды), я думаю, что наличие частный флаг лучше для ясности и обслуживания.

0
ответ дан 14 December 2019 в 19:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: