Контакт с.NET объекты IDisposable

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

40
задан Community 23 May 2017 в 10:29
поделиться

11 ответов

FxCop мог бы справка (хотя это не определило тест, я просто выстрелил в него); но да: Вы предназначены для проверки. IDisposable просто такая важная часть системы, что необходимо войти в эту привычку. Используя intellisense для поиска .D хорошее начало (хотя не прекрасный).

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

ReSharper делает задание также, предлагая "помещенный в использование конструкции" опция. Это не предлагает его как ошибку, хотя...

, Конечно, если Вы не уверены - попытка using это: компилятор будет смеяться насмешливо над Вами, если Вы будете параноиками:

using (int i = 5) {}

Error   1   'int': type used in a using statement must be implicitly convertible to 'System.IDisposable'    
24
ответ дан Chris Laplante 27 November 2019 в 01:49
поделиться

Всегда пытайтесь использовать блоки "использования". Для большинства объектов это не имеет большое значение однако, я встретился с недавней проблемой, где я реализовал элемент управления ActiveX в классе, и в не вымылся корректно, если Расположение не назвали правильно. Нижняя строка - то, даже если это, кажется, не имеет большую часть значения, попытайтесь сделать это правильно, потому что некоторое время это будет иметь значение.

0
ответ дан Ryan 27 November 2019 в 01:49
поделиться

Я использую блоки использования, прежде всего, для этого сценария:

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

Ради аргумента, позволяет, говорят, что у меня есть 11 точек выхода к моему методу, 10 из которых в этом блоке использования и 1 после него (который может быть типичным в некотором коде библиотеки, который я записал).

, Так как от объекта автоматически избавляются при выходе из блока использования, у меня не должно быть 10 различных.Dispose () вызовы - это просто происходит. Это приводит к более чистому коду, так как он теперь менее нарушен, располагают вызовы (~10 меньше строк кода в этом случае).

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

1
ответ дан James 27 November 2019 в 01:49
поделиться

К сожалению, никакой FxCop или StyleCop, кажется, не предупреждают об этом. Как другие комментаторы упомянули, обычно довольно важно удостовериться, что звонило, располагают. Если я не уверен, я всегда проверяю Обозреватель объектов (Ctrl+Alt+J) для рассмотрения дерева наследования.

1
ответ дан Brent Rockwood 27 November 2019 в 01:49
поделиться

Как Fxcop (с которым они связаны), инструменты анализа кода в VS (если у Вас есть один из выпусков большой шишки) найдут эти случаи также.

0
ответ дан Will Dean 27 November 2019 в 01:49
поделиться

@Atario, не только принятый ответ является неправильным, Ваше собственное редактирование также. Вообразите следующую ситуацию (, который на самом деле произошел в одном CTP Visual Studio 2005):

Для рисования графики, Вы создаете перья, не располагая их. Перья не требуют большой памяти, но они используют GDI + дескриптор внутренне. Если Вы не расположите перо, GDI +, то дескриптор не будет выпущен. Если Ваше приложение не является интенсивно использующим память, некоторое время может передать без называемого GC. Однако количество доступного GDI + дескрипторы ограничиваются и достаточно скоро, когда Вы попытаетесь создать новое перо, операция перестанет работать.

На самом деле, в Visual Studio 2005 CTP при использовании приложения достаточно долго все шрифты внезапно переключились бы на “System”.

Это точно, почему это недостаточно для доверия GC для расположения. Использование памяти не обязательно взаимосвязывает с количеством неуправляемых ресурсов, которые Вы получаете (и не выпускайте). Поэтому эти resoures могут быть исчерпаны задолго до того, как GC называют.

Кроме того, существуют, конечно, целые аспекты побочных эффектов, которые могут иметь эти ресурсы (такие как блокировки доступа), которые препятствуют тому, чтобы другие приложения работали правильно.

3
ответ дан Konrad Rudolph 27 November 2019 в 01:49
поделиться

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

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

А хороший пример этого - то, где класс использует частный EventWaitHandle (или AutoResetEvent) для передачи между двумя потоками, и Вы хотите Избавиться от WaitHandle, как только поток закончен.

, Таким образом, это не столь просто как некоторый инструмент, просто проверяющий, что Вы только создаете объекты IDisposable в using блок.

4
ответ дан Community 27 November 2019 в 01:49
поделиться

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

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

вся эта мысль позади расположить шаблона состоит в том, что Вы обеспечиваете несколько детерминированный способ выпустить неуправляемый ресурсы, сохраняемые объектом (или любой объект в, он - цепочка наследования). Не звоня Dispose() правильно Вы абсолютно можете выполненный в к утечке памяти (или любое количество других проблем).

Dispose() метод ни в коем случае не связан с деструктором. Самым близким, который Вы получаете к деструктору в.NET, является финализатор. Оператор использования не делает никакого освобождения... на самом деле, вызов Dispose() не делает никакого освобождения на управляемой "куче"; это только высвобождает неуправляемые средства, которые были выделены. Управляемые ресурсы истинно не освобождены, пока GC не выполняет и собирает пространство памяти, выделенное тому графу объектов.

лучшие способы определить, реализует ли класс IDisposable:

  • IntelliSense (если это имеет Dispose() или Close() метод)
  • отражатель MSDN
  • Компилятор (если это не реализует IDisposable, Вы получаете ошибку компилятора)
  • Здравый смысл (если это чувства как Вы должно закрыться/выпустить объект после того, как Вы сделаны, тогда Вы, вероятно должны )
  • Семантика (если существует Open(), существует, вероятно, соответствие Close(), который нужно назвать)
  • компилятор. Попытайтесь поместить его в using оператор. Если это не реализует IDisposable, компилятор генерирует ошибку.

Думают о расположить шаблоне, как являющемся всеми об управлении времени жизни объема. Вы хотите получить ресурс максимально в последний раз, использовать так же быстро как возможно и выпустить как можно скорее. Оператор использования помогает сделать это путем обеспечения, что вызов к [1 114] будет выполнен, даже если будут исключения.

15
ответ дан Scott Dorman 27 November 2019 в 01:49
поделиться

Поэтому (по моему скромному мнению), RAII C++ превосходит.NET using оператор.

Много людей сказало, что IDisposable только для неуправляемых ресурсов, это только верно в зависимости от того, как Вы определяете "ресурс". У Вас может быть блокировка Чтения-записи, реализовывая IDisposable, и затем "ресурс" является концептуальным доступом к блоку кода. У Вас может быть объект, который изменяет курсор на песочные часы в конструкторе и назад на ранее сохраненное значение в IDispose, и затем "ресурс" является измененным курсором. Я сказал бы, что Вы используете IDisposable, когда Вы хотите, чтобы детерминированное действие произошло при отъезде объема, неважно, как объем оставляют, но я должен признать, что это является намного менее броским, чем высказывание, "это для управления управлением неуправляемого ресурса".

Видят также вопрос [приблизительно 114], почему нет никакого RAII в.NET .

4
ответ дан Community 27 November 2019 в 01:49
поделиться

Я действительно не имею ничего для добавления к общему использованию Использования блоков, но просто хотел добавить исключение из правила:

Любой объект, который реализует IDisposable, по-видимому, не должен выдавать исключение во время Располагать () метод. Это работало отлично до WCF (могут быть другие), и теперь возможно, что исключение выдается каналом WCF во время, Располагают (). Если это происходит, когда это используется в Использовании блока, это вызывает проблемы и требует реализации обработки исключений. Это, очевидно, требует большего знания внутренних работ, которое является, почему Microsoft теперь рекомендует не использовать каналы WCF в Использовании блоков (извините не мог найти ссылку, но много других результатов в Google), даже при том, что это реализует IDisposable.. Только сделать вещи более сложными!

2
ответ дан The Giraffe 27 November 2019 в 01:49
поделиться

Согласно этой ссылке дополнение CodeRush будет обнаруживать и отмечать, когда локальные переменные IDisposable не очищаются, в реальном времени, по мере ввода текста.

Могу встретиться с вами на полпути в ваших поисках.

0
ответ дан 27 November 2019 в 01:49
поделиться