Мне сказали ту Систему. IO.MemoryStream не должен быть обернут в блок использования, потому что нет никакого базового ресурса, это отчасти идет вразрез с тем, что мне всегда говорили о потоках ("если в сомнении, используйте использование").
Действительно ли это верно? Почему тогда пример MSDN использует один (полученный в итоге ниже)?
using(MemoryStream memStream = new MemoryStream(100))
{
// do stuff
}
C # IDIOM заключается в том, что если объектная реализация IDSPosable
, вы используете , используя блок
. Это позволит всем ресурсам, используемым объектом, быть утилизированным должным образом. Вы не должны знать детали реализации MemoryStream
. То, что вы знаете, это то, что он реализует IDSposable
, чтобы вы должны правильно утилизировать его. Кроме того, вы думаете, что вы теперь знаете, что ему не нужно иметь никаких ресурсов, но как вы знаете, что в будущем MemoryStream
не изменит свою базовую реализацию, чтобы он использовал ресурсы, которые необходимо Быть освобожденным с использованием Dispose
? Вы этого не сделаете, так как он реализует IDissoable
У вас есть больше будущего кода, просто используя шаблон сейчас. Во-вторых, что, если вы измените свой код в будущем, чтобы использовать другой тип поток
, который имеет управляемые ресурсы? Оборачивая MemoryStream
в , используя блок
, теперь вы сокращаете проблемы технического обслуживания в будущем; Опять же, это правильный способ использования объектов, а также в частности поток
, который реализуется IDSPosable
. В-третьих, это четкий способ сигнала для читателей, которые вы делаете с использованием объекта; Это то, что читатели вашего кода будут ожидать, когда они увидят, что вы используете объекты, которые реализуют IDSPosable
. Наконец, это текущая реализация 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
, теперь он становится непригодным для них, что может быть хорошей вещью. Но это действительно наименее важный вопрос; Детали реализации не имеют значения.
Используйте , используя блок
, поскольку MemoryStream
Allurage IDissoable
. Не используйте , используя блок
, потому что вы думаете, что MemoryStream
не имеет никаких ресурсов, которые необходимо освободить.
Если он реализует IDisposable, вы должны избавиться от него. Вы просто работаете с API и не знаете о реализации, поэтому у вас нет причин не помещать его в блок using.
Беглый взгляд на Reflector показывает, что Dispose
в MemoryStream
мало что иное, как отметка поток как не открытый, доступный для записи или расширения.
При этом в качестве общего подхода вам, вероятно, следует придерживаться шаблона удаления; тем более, что все потоки Stream
следуют подходу "декоратора" и должны легко заменяться друг на друга или оборачиваться друг с другом. Сегодняшний MemoryStream
может быть заменен другим потоком, который завтра действительно важен.
Если класс реализует IDisposable, его следует удалить.
Вам не нужно беспокоиться о том, делает ли это что-нибудь значимое или нет - класс должен решить и реализовать. Если класс ничего не делает, когда объект удаляется, то в любом случае ничего не стоит, так что вреда нет.
Инкапсуляция - один из краеугольных камней объектно-ориентированной разработки. Зачем изо всех сил нарушать это, особенно если нет веской причины?
Вы не теряете ничего, упаковывая поток памяти в блоке с использованием, поэтому, если есть сомнения, просто сделайте это. :)
Как сказал Charlie , рекомендуется рекомендуемую практику для утилизации всех объектов классов, которые реализуются IDSPolitable.
Если вы посмотрите в реализацию 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);
}
}