Пара моментов:
Вызов Dispose
не увеличивает производительность. IDisposable
разработан для сценариев, в которых вы используете ограниченные и / или неуправляемые ресурсы, которые не могут быть учтены средой выполнения.
Нет четкого и очевидного механизма того, как компилятор может обрабатывать IDisposable
объекты в коде. Что делает его кандидатом на автоматическую утилизацию, а что нет? Если экземпляр (или может) быть представлен вне метода? Ничего не сказать, что только потому, что я передаю объект другой функции или классу, я хочу, чтобы его можно было использовать за пределами метода.
Рассмотрим, например, шаблон фабрики, который принимает Stream
и десериализует экземпляр класса.
public class Foo
{
public static Foo FromStream(System.IO.Stream stream) { ... }
}
И я называю это:
Stream stream = new FileStream(path);
Foo foo = Foo.FromStream(stream);
Теперь я могу или не хочу, чтобы этот Stream
удалялся при выходе из метода. Если фабрика Foo
считывает все необходимые данные с Stream
и больше не нуждается в них, я бы хотел, чтобы она была утилизирована. Если объект Foo
должен удерживать поток и использовать его на протяжении всего времени существования, я бы не хотел, чтобы он удалялся.
Точно так же как насчет экземпляров, которые извлекаются из чего-то другого, кроме конструктора, например Control.CreateGraphics()
. Эти экземпляры могут существовать вне кода, поэтому компилятор не будет избавляться от них автоматически.
Предоставление пользователю управления (и предоставление идиомы, такой как блок using
) проясняет намерение пользователя и значительно упрощает обнаружение мест, где IDisposable
экземпляры не удаляются должным образом. Если бы компилятор автоматически удалял некоторые экземпляры, то отладка была бы намного сложнее, поскольку разработчику приходилось расшифровывать, как правила автоматического удаления применяются к каждому блоку кода, который использовал объект IDisposable
. .
В конце концов, есть две причины (по соглашению) для реализации IDisposable
для типа.
- Вы используете неуправляемый ресурс (это означает, что вы выполняете вызов P / Invoke, который возвращает что-то вроде дескриптора, который должен быть освобожден другим вызовом P / Invoke)
- В вашем типе есть экземпляры
IDisposable
, которые следует удалить по истечении срока жизни этого объекта.
В первом случае предполагается, что все такие типы реализуют финализатор, который вызывает Dispose
и освобождает все неуправляемые ресурсы, если разработчик не может этого сделать (это необходимо для предотвращения утечек памяти и обработки).
person
Adam Robinson
schedule
17.06.2010