Явное преобразование в IDisposable - PullRequest
2 голосов
/ 02 июля 2011

Я использую некоторые объекты XmlReader и XmlWriter для выполнения необходимой работы со строками внутри некоторых блоков try...catch.

Я знаю, что использование обозначения using (XmlReader NewReader = XmlReader.Create(...)) является предпочтительным синтаксисом, но мне это не очень нравится, поэтому я также добавляю finally блоки и выполняю NewReader.Close(); и NewWriter.Close();.

Однако анализ кода жалуется на то, что эти объекты не удаляются, что вынуждает меня каким-то образом вызывать метод Dispose().

Проблема в том, что в этих классах метод Dispose() реализован явно, поэтому я должен использовать ((IDisposable)(NewReader)).Dispose(); и ((IDisposable)(NewWriter)).Dispose();.

Есть ли недостатки этой техники?

Ответы [ 3 ]

4 голосов
/ 02 июля 2011

Есть веские причины не использовать using:

  • Когда время жизни объекта может потребоваться дольше, чем текущий блок

и есть плохие причины избегать using:

  • «Мне это не очень нравится»

Применима ли уважительная причина к вашему коду?

Обратите также внимание, что простой метод расширения снова сделает синтаксис красивым и чистым.

1 голос
/ 02 июля 2011

Оператор C # using всегда будет вызывать Dispose для вас.Это примерно соответствует следующему:

XmlReader NewReader = XmlReader.Create(...);
try
{
   // do stuff on NewReader 
}
finally
{
    ((IDisposable)NewReader).Dispose();
}

Так что завертывание в finally само по себе не добавляет никакой ценности.Хотя Close и Dispose часто эквивалентны, это не всегда так.Поскольку этот FxCop правильный, вы всегда должны вызывать Dispose, и когда вы делаете это (или позволяете оператору using делать это), нет никаких причин вызывать Close вручную.

1 голос
/ 02 июля 2011

Оператор using действительно является предпочтительным решением. Это идиоматично в C #. Эти классы реализуют IDisposable явно, потому что они уже предоставляют метод с закрывающей семантикой: Close. Я держу пари, что Dispose звонит Close или наоборот. Но вы не должны на это рассчитывать и всегда должны звонить Dispose.

В конце концов, все это эквивалентно:

  1. Используйте using, что является предпочтительным;
  2. Вызовите Close в блоке finally и подавьте предупреждения статического анализа или;
  3. Звоните Dispose на finally: ((IDisposable)NewReader).Dispose();
...