Явная реализация IDisposable - PullRequest
14 голосов
/ 07 апреля 2011

Хотя есть довольно много вопросов и ответов относительно IDisposable, которые можно найти на SO, я пока не нашел ответа на этот вопрос:

Я обычно следую практике, когда один из моих классов владеетобъект IDisposable, тогда он также реализует IDisposable и вызывает Dispose для принадлежащего объекта.Однако недавно я наткнулся на класс, который явно реализовал IDisposable, что не позволяло мне напрямую вызывать Dispose, заставляя меня разыграть его, что я нашел раздражающим и ненужным.

Итак, вопрос: почему и когда кто-то захочетиспользовать явную реализацию интерфейса IDisposable?Я знаю, что есть совершенно веская и веская причина для явной реализации интерфейса, но в отношении IDisposable причина мне не совсем ясна.

Ответы [ 3 ]

15 голосов
/ 07 апреля 2011

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

В этом случае ваш класс-оболочка может вызывать Close, а не приведение.

Примером является класс WebResponse в Framework <= V3.5.Интересно, что в .NET 4 есть публичный метод Dispose, поэтому, возможно, Microsoft сейчас решила, что явная реализация не может быть хорошей практикой. </p>

Шон Фаркас, инженер-конструктор из команды безопасности CLR, пишет в Журнал MSDN that

Хотя блок using будет работать с классами, которые имеют явную реализацию IDisposable, я рекомендую, чтобы классы никогда не реализовывали интерфейс таким способом.Если вы явно реализуете IDisposable, разработчики, которые изучают вашу объектную модель с использованием IntelliSense® в Visual Studio®, не заметят, что у объекта есть метод Dispose

1 голос
/ 16 апреля 2011

ИМХО, у класса есть только одна правильная причина для явной реализации IDisposable, которая могла бы быть, если бы ожидалось, что никто на самом деле не должен будет вызывать его. Тот факт, что класс реализует IDisposable в явном виде, может рассматриваться как показатель того, что можно безопасно создать объект этого конкретного класса , хотя не обязательно объект производного класса, и просто отказаться от него, когда он будет сделан с этим. Отсутствие непосредственно доступного метода Dispose для определенного класса можно было бы тогда рассматривать как индикатор того, что вызов Dispose для объекта, который, как известно, принадлежит к этому конкретному классу, не понадобится.

Обратите внимание, что наличие и использование ссылки на объект, который реализует IDisposable, без понимания того, что он делает, не является проблемой; приобретение владения таким объектом, однако, является. Фабричный метод, тип возвращаемого значения которого ничего не делает с IDisposable.Dispose и реализует его явным образом, но который иногда возвращает объект, ожидающий правильного удаления, может быть рецептом для утечек. Класс не должен явно реализовывать IDisposable, если он может использоваться в качестве типа возврата такого фабричного метода.

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

1 голос
/ 07 апреля 2011

Я бы сказал, что это хорошая практика, она заставляет (если вы не хотите привести к IDisposable !!) использование

using (ClassWithIDisposable) {
}

Утилита будет вызываться даже в случае исключения

Кроме того, при использовании IOC-фреймворков, таких как замок и единство, вам приходится наследовать ID, доступный для вашего интерфейса, чтобы его можно было вызывать. Эти фреймворки позволяют использовать AOP, поэтому у вас нет ссылки только на интерфейс класса ...

...