Упаковка MemoryStream в использование
Мне сказали, что System.IO.MemoryStream не нужно заключать в блок использования, потому что нет базового ресурса, это противоречит тому, что мне всегда говорили о потоках ("если сомневаетесь, используйте использование"),
Это правда? Почему тогда в примере MSDN используется один (приведенный ниже)?
using(MemoryStream memStream = new MemoryStream(100))
{
// do stuff
}
6 ответов
Идиома C# в том, что если объект реализует IDisposable
тогда вы используете using
блок. Это позволит правильно использовать все ресурсы, используемые объектом. Вы не должны знать детали реализации MemoryStream
, То, что вы знаете, это то, что он реализует IDisposable
так что вы должны утилизировать его правильно. Кроме того, вы думаете, что теперь знаете, что не нужно освобождать какие-либо ресурсы, но как вы узнаете об этом в будущем MemoryStream
не изменит свою базовую реализацию, чтобы он использовал ресурсы, которые должны быть освобождены с помощью Dispose
? Вы не так, так как он реализует IDispoable
у вас есть больше кода на будущее, просто используя шаблон сейчас. Во-вторых, что если вы в будущем измените свой код, чтобы использовать другой тип Stream
что есть управляемые ресурсы? Заворачивая MemoryStream
в using
блокировать сейчас вы уменьшите проблемы с обслуживанием в будущем; опять же, это правильный способ использования объектов, и конкретно Stream
которые реализуют IDisposable
, В-третьих, это четкий способ дать понять читателям, что вы закончили с использованием объекта; это то, что читатели вашего кода ожидают увидеть, когда увидят, что вы используете объекты, которые реализуют IDisposable
, Наконец, это текущая реализация MemoryStream.Dispose
:
protected override void Dispose(bool disposing) {
try {
if (disposing) {
this._isOpen = false;
this._writable = false;
this._expandable = false;
}
}
finally {
base.Dispose(disposing);
}
}
Таким образом, этот поток помечается как закрытый, недоступный для записи и не расширяемый. Если кто-то еще заполучил ссылку на то же самое MemoryStream
, теперь он становится непригодным для них, что может быть хорошей вещью. Но это действительно наименее важный вопрос; детали реализации не имеют значения.
Использовать using
блок, потому что MemoryStream
воплощать в жизнь IDispoable
, Не используйте using
блокировать, потому что вы думаете, что MemoryStream
не имеет никаких ресурсов, которые должны быть освобождены.
Рекомендация заключается в том, что если он реализует IDisposable, то вы должны избавиться от него. Вы просто работаете с API и не знаете о реализации, поэтому у вас нет причин не помещать его в блок using.
Беглый взгляд в Reflector, кажется, что Dispose
на MemoryStream
не делает ничего, кроме как пометить поток как не открытый, доступный для записи или расширяемый.
Сказав, что, как общий подход, вы, вероятно, должны придерживаться шаблона утилизации; особенно как Stream
Все они следуют подходу "декоратор" и должны легко заменяться друг на друга или оборачиваться друг с другом. Сегодняшние MemoryStream
может быть заменено другим потоком, который заботится завтра.
Если класс реализует IDisposable, он должен быть удален.
Вам не нужно угадывать, делает ли это что-то значимое или нет - это должен решать и реализовывать класс. Если класс ничего не делает, когда объект утилизируется, то все равно на самом деле нет никаких затрат, поэтому нет никакого вреда.
Инкапсуляция является одним из краеугольных камней объектно-ориентированной разработки. Зачем изо всех сил ломать это, особенно если нет веской причины?
Как сказал Чарли, рекомендуется утилизировать все объекты классов, которые реализуют IDisposable.
Если вы посмотрите на реализацию MemoryStream.Dispose(bool) (которая вызывается Stream.Dispose()), становится очевидным, что вы должны избавиться от нее, поскольку она обновляет несколько флагов управления:
protected override void Dispose(bool disposing)
{
try
{
if (disposing)
{
this._isOpen = false;
this._writable = false;
this._expandable = false;
}
}
finally
{
base.Dispose(disposing);
}
}
Вы ничего не потеряете, обернув поток памяти в блок использования, поэтому, если есть сомнения, просто сделайте это.:)