Могу ли я "встроить" переменную, если она IDisposible? - PullRequest
11 голосов
/ 11 февраля 2010

Должен ли я сделать это, чтобы обеспечить правильное удаление MemoryStream?

  using (MemoryStream stream = new MemoryStream(bytes))
  using (XmlReader reader = XmlReader.Create(stream))
  {
    return new XmlDocument().Load(reader);
  }

или это нормально, чтобы встроить MemoryStream так, чтобы он просто вышел из области видимости? Как это?

  using (XmlReader reader = XmlReader.Create(new MemoryStream(bytes)))
  {
    return new XmlDocument().Load(reader);
  }

Ответы [ 6 ]

11 голосов
/ 11 февраля 2010

Как правило, да, вы должны написать код, как в первом примере.

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

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

Так что, как правило, используйте первый синтаксис.

Теперь для указанного примера это не должно иметь большого значения, поскольку MemoryStream на самом деле не удерживает ресурсы, которые необходимо утилизировать, но с этим ожиданием тоже есть проблема. Если вы знаете, что данная версия объекта не использует ресурс, поэтому можно игнорировать Dispose, тогда, если этот объект в будущем получит такой ресурс, вы внезапно получите утечку.

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

10 голосов
/ 11 февраля 2010

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

4 голосов
/ 11 февраля 2010

Существует возможность использовать XmlReaderSettings и установить для параметра CloseInput значение true, как это

var reader = XmlReader.Create(new MemoryStream(), new XmlReaderSettings {CloseInput = true});

Здесь: Свойство XmlReaderSettings.CloseInput

3 голосов
/ 11 февраля 2010

Это действительно зависит от Dispose () XmlReader.Потребовалась бы некоторая работа, чтобы выяснить, что именно она делает.Я лично пишу код, как в первом примере.Если вы что-то новое, то это ваша ответственность, чтобы распоряжаться этим.Вы не должны ожидать, что другие позаботятся об этом за вас (хотя они могут).

2 голосов
/ 11 февраля 2010

Вы говорите о двух разных вещах:

  1. С точки зрения передового опыта проектирования, всегда ли вы должны располагать объектом, за который несете ответственность? Да
  2. Собираетесь ли вы испытать утечку памяти в соответствии с шаблоном, показанным во втором примере? Нет , если только по той причине, что MemoryStream.Dispose на самом деле ничего не делает .
0 голосов
/ 11 февраля 2010

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

...