Почему класс реализует IDisposable явно, а не неявно?
Я использовал класс FtpWebResponse и не видел метод Dispose. Оказывается, что класс реализует IDisposable, но делает это явно, так что вы должны сначала привести ваш экземпляр к IDisposable перед вызовом Dispose:
// response is an instance of FtpWebResposne
((IDisposable) response).Dispose();
Почему разработчик такого класса, как этот, решил явно реализовать IDisposable? Как говорит Энтони Пеграм, такие действия маскируют тот факт, что объект должен быть расположен для среднего разработчика, который не обращается к документации каждый раз, когда он / она использует класс.
4 ответа
Обычно это делается, если у класса есть Close
метод, который точно такой же, как Dispose
, Оригинал Dispose
скрыт в явной реализации, так что один и тот же метод не имеет двух имен.
Это официально рекомендуется здесь:
Реализуйте метод Close для целей очистки, если такая терминология стандартна, например, для файла или сокета. При этом рекомендуется сделать реализацию Close идентичной Dispose...
Иногда доменное имя более подходит, чем Dispose. Например, при инкапсуляции файла может потребоваться использовать имя метода Close. В этом случае внедрите Dispose для частного использования и создайте открытый метод Close, который вызывает Dispose.
(PS Я не согласен с этим соглашением.)
- Иногда класс будет иметь метод Dispose, который является частью интерфейса, но на самом деле его не нужно вызывать, потому что единственным ресурсом, которым можно распоряжаться, является память: например, MemoryStream.
- Как уже упоминалось другими, если в классе есть метод Close, который делает то же самое, что и Dispose, возможно, Dispose должен существовать только для поддержки шаблона "using", поэтому он также может быть явным.
В дополнение к тому, что было сказано, я мог бы предложить IDisposable
явно поощряет использование using
блок, так как он может быть использован на любом типе, который реализует IDisposable
и это более естественно (для большинства людей, так или иначе) написать это:
using (var response = GetResponse())
{
// do something
}
Чем это:
var response = GetResponse();
// do something
((IDisposable)response).Dispose();
Я не уверен, что это было бы намерением разработчика в явной реализации IDisposable
, но это возможно.
Это немного странно смотреть на меня тоже. Для чего это стоит: базовый класс (WebResponse) реализует метод Close(). Отражатель показывает, что метод Dispose () WebResponse просто вызывает Close() и виртуальный OnDispose, который ничего не делает.
Я должен признаться, что это немного пахнет для меня, но я держу пари, что они явно реализовали IDisposable, чтобы не было путаницы в Intellisense между вызовом Close() или Dispose ().