Подтвердить что ты не робот

Почему класс должен реализовать IDisposable явно, а не неявно?

Я использовал класс FtpWebResponse и не видел метод Dispose. Оказывается, что класс реализует IDisposable, но делает это явно, чтобы вы сначала перенесли свой экземпляр в IDisposable перед вызовом Dispose:

// response is an instance of FtpWebResposne
((IDisposable) response).Dispose();

Почему разработчик такого класса, как этот, может явно реализовать IDisposable? Как говорит Энтони Пегем, выполнение подобных действий маскирует тот факт, что объект должен быть утилизирован для среднего разработчика, который не обращается к документации каждый раз, когда он/она использует класс.

4b9b3361

Ответ 1

Обычно это делается, если класс имеет метод Close, который является таким же, как Dispose. Оригинальный Dispose скрыт в явной реализации, так что тот же самый метод не имеет двух имен.

Официально здесь рекомендуется:

Выполняйте метод Close для целей очистки, если такая терминология является стандартной, например, как с файлом или сокетом. При этом рекомендуется, чтобы реализация Close была идентичной Dispose...

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

Иногда доменное имя более подходит, чем Dispose. Например, инкапсуляция файла может захотеть использовать имя метода Close. В этом случае реализуйте Dispose в частном порядке и создайте общедоступный метод Close, который вызывает Dispose.

(P.S. Я не согласен с этим соглашением.)

Ответ 2

  • Иногда класс будет иметь метод Dispose, который является частью интерфейса, но на самом деле его не нужно вызывать, потому что единственным ресурсом, которым нужно распоряжаться, является память: MemoryStream, например.
  • Как уже упоминалось другими, если класс имеет метод Close, который выполняет то же самое, что и Dispose, возможно, Dispose должен существовать только для поддержки шаблона "using", чтобы он мог быть явным.

Ответ 3

Это немного странно, глядя на меня тоже. Для чего это стоит: базовый класс (WebResponse) реализует метод Close(). Отражатель показывает, что метод WebResponse Dispose() просто вызывает Close() и виртуальный виртуальный виртуальный OnDispose, который ничего не делает.

Я должен признаться, что он немного пахнет мне, но я уверен, что они явно реализовали IDisposable, чтобы не было путаницы в Intellisense между вызовом Close() или Dispose().

Ответ 4

В дополнение к тому, что было сказано, я могу предположить, что реализация IDisposable явно поощряет использование блока using, поскольку его можно использовать для любого типа, реализующего IDisposable, и это более естественно (для большинства людей, в любом случае), чтобы написать это:

using (var response = GetResponse())
{
    // do something
}

Чем это:

var response = GetResponse();

// do something

((IDisposable)response).Dispose();

Я не уверен, что это было бы намерение разработчика в явной реализации IDisposable, но это возможно.