Шаблон удаления: как узнать, что является управляемым, а что неуправляемым?

Читая о шаблоне Dispose, я вижу документацию повторно ссылайтесь на "очистку управляемого и неуправляемого кода". И в канонической реализации метода Dispose я вижу определенные потоки (в зависимости от того, истинно или ложно disposing), посвященные очистке управляемых объектов по сравнению с неуправляемыми объектами.

Но разве я, скромный новичок, должен знать, какие типы управляемые, а какие неуправляемые?


person Jeff Stewart    schedule 10.07.2009    source источник


Ответы (5)


Короткая версия: все, что также реализует IDisposable, должно вызываться в вашем методе Dispose. FxCop также сообщит вам, если вы пропустили что-то (или вообще не использовать IDisposable, когда нужно).

person Matthew Scharley    schedule 10.07.2009
comment
Хотя это на самом деле не отвечает на вопрос, я больше не уверен, что существует хороший ответ. Это обеспечивает наилучшее практическое решение проблем, возникающих, когда программист не может судить об управляемости типа, но я думаю, что программисту, которому нужна окончательная эвристика для вынесения такого суждения, просто не повезло. - person Jeff Stewart; 12.08.2009

Неуправляемые означают собственные объекты Win32, в основном дескрипторы; и ссылки на необработанные COM-объекты. Это ресурсы, которые не находятся под контролем (или не управляются) .NET CLR.

person John Saunders    schedule 10.07.2009
comment
Верно, но как разработчику строго .NET, слишком молодому, чтобы использовать Win32, COM и т. д., узнать, что ресурс не находится под контролем CLR или, что еще хуже, зависит на ресурсе, который не находится под управлением CLR? Я имею в виду, как вы узнаете, что, скажем, дескриптор неуправляемый? Наверное опыт. Но при отсутствии такого опыта, как более экологичному программисту каждый раз делать все правильно? Я утверждаю, что наличия, скажем, интерфейса IDisposable недостаточно; вашего среднего программиста не учат проверять документацию каждого типа на предмет упоминания IDisposable. - person Jeff Stewart; 14.07.2009
comment
Я говорю обратное. Если IDisposable есть, то утилизируйте. Период. Таким образом, нежной молодежи никогда не придется подвергаться травме COM. - person John Saunders; 14.07.2009

Управляемый или неуправляемый не имеет большого значения. Если класс реализует интерфейс IDisposable, вы должны вызвать Dispose(), когда закончите с объектом. В качестве альтернативы (предпочтительно) используйте оператор using чтобы Dispose() вызывался автоматически, когда объект выходит за пределы области видимости.

@ Роб:
Ответ все тот же. Если ваш класс управляет любыми внутренними объектами, реализующими IDisposable, он также должен реализовывать IDisposable. В вашем методе Dispose() вызовите Dispose для этих объектов.

person Thorarin    schedule 10.07.2009
comment
Я думаю, что вопрос задавался с точки зрения разработки IDisposables, то есть что следует и не следует освобождать при удалении или доработке. - person Rob; 11.07.2009
comment
@Thorarin - я думаю, что смысл Роба в том, что если вы реализуете классический шаблон удаления, у вас есть флаг isDispose, чтобы указать, удаляется ли он из-за вызова удаления или из-за выполнения финализатора. В последнем случае вам нужно быть осторожным, чтобы не удалять другие управляемые объекты, поскольку они, возможно, уже были удалены сборщиком мусора. Безопасно ли удалять их при явном вызове из метода Dispose(). Однако неуправляемый ресурс должен быть удален в обоих случаях. - person Rob Levine; 11.07.2009
comment
Я склоняюсь к гестаповскому подходу в этом вопросе: если финализатор вообще вызывается, громко жалуйтесь программисту, чтобы он поправил их код. - person Thorarin; 11.07.2009

Я бы просто предложил уничтожить все ресурсы после их использования. Все, что обычно зависит от системного ресурса, такого как сокеты и потоковые ресурсы, которые вы хотите явно освободить. Если вы сомневаетесь, идите и утилизируйте. В долгосрочной перспективе избавляет вас от многих проблем с отладкой. Обычно, когда вы вызываете код, написанный не на .NET, вы можете предположить, что это не "управляемый код".

person Achilles    schedule 10.07.2009

Если вы не знаете, используемые вами типы, вероятно, являются управляемыми.

Неуправляемые типы относятся к типам, которые не являются безопасными, то есть не соответствуют требованиям безопасности среды CLR.

Ссылка на отличное определение:

Обновить

Я не понимаю минус? Вопрос заключался в том, как различать управляемые и неуправляемые типы?

Все остальные ответы касались вопроса IDispose, а не управляемого/неуправляемого вопроса!?

Обновление 2

До сих пор нет объяснения второго отрицательного голоса...

Я согласен, объект IDisposable всегда должен удаляться, но это не отвечает на вопрос об управляемом и неуправляемом.

person John Weldon    schedule 10.07.2009
comment
Подобно моему другому комментарию, откуда вы знаете, что тип, как вы говорите, не соответствует требованиям безопасности CLR? т.е. если бы я написал подключаемый модуль Reflector для сообщения о неуправляемости выбранного типа, что бы мой подключаемый модуль проверял для этого типа, чтобы вынести окончательное суждение? - person Jeff Stewart; 14.07.2009