обертывание MemoryStream в использовании

Мне сказали ту Систему. IO.MemoryStream не должен быть обернут в блок использования, потому что нет никакого базового ресурса, это отчасти идет вразрез с тем, что мне всегда говорили о потоках ("если в сомнении, используйте использование").

Действительно ли это верно? Почему тогда пример MSDN использует один (полученный в итоге ниже)?

using(MemoryStream memStream = new MemoryStream(100))
{
            // do stuff
}

10
задан gingerbreadboy 8 January 2010 в 16:48
поделиться

6 ответов

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 не имеет никаких ресурсов, которые необходимо освободить.

26
ответ дан 3 December 2019 в 13:29
поделиться

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

6
ответ дан 3 December 2019 в 13:29
поделиться

Беглый взгляд на Reflector показывает, что Dispose в MemoryStream мало что иное, как отметка поток как не открытый, доступный для записи или расширения.

При этом в качестве общего подхода вам, вероятно, следует придерживаться шаблона удаления; тем более, что все потоки Stream следуют подходу "декоратора" и должны легко заменяться друг на друга или оборачиваться друг с другом. Сегодняшний MemoryStream может быть заменен другим потоком, который завтра действительно важен.

5
ответ дан 3 December 2019 в 13:29
поделиться

Если класс реализует IDisposable, его следует удалить.

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

Инкапсуляция - один из краеугольных камней объектно-ориентированной разработки. Зачем изо всех сил нарушать это, особенно если нет веской причины?

4
ответ дан 3 December 2019 в 13:29
поделиться

Вы не теряете ничего, упаковывая поток памяти в блоке с использованием, поэтому, если есть сомнения, просто сделайте это. :)

3
ответ дан 3 December 2019 в 13:29
поделиться

Как сказал 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);
    }
}
3
ответ дан 3 December 2019 в 13:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: