Я понимаю, что это старая ветка, но кое-что упущено.
Шаблон размещения в C # и Java нарушает фундаментальную причину отсутствия детерминированного деструктора.
MyObject A = new MyObject()
MyObject B = A;
A.Dispose();
Каково состояние Б сейчас? Что, если владелец Б действительно не хочет, чтобы он был распущен. Теперь у вас есть та же проблема в C ++, где вы должны отслеживать все ссылки на объекты, к которым вы держитесь.
IDisposable
действительно действительно только в контексте using()
и обеспечивает очистку ресурса в случае возникновения исключения.
Для этого есть шаблоны проектирования, но это не IDisposable
@ Peter Да, я утверждаю, что шаблон Dipsosable имеет ошибку. При реализации шаблон Disposable обычно не подразумевает просто распоряжение ресурсами ОС с идеей возможности продолжать использовать объект, который был удален. Используя шаблон Disposable вне try {} finally {} в Java или используя () в .NET, вы устраняете одну из причин наличия GC. Я не говорю, что память будет течь. Я говорю, что теперь вы можете иметь другие части кода, которые имеют ссылку на объект, который был удален. Теперь ответственность за то, чтобы объект был удален перед каждым вызовом, возложена на разработчика или по крайней мере перехватывает исключение ObjectDisposedException.
Давайте посмотрим на глупый пример:
FileStream stream = new FileStream (@"c:\mylog.txt");
logger.setStream (stream);
Кто должен вызывать .Dispose ()? Может не быть очевидным, что регистратор теперь получает право собственности на файловый поток. Допустим, поток был создан где-то еще за пределами разработчика, зная, что он будет установлен как поток регистрации.
если бы мы добавили одну строку, мы бы сломали регистратор
using (FileStream stream = new FileStream (@"c:\mylog.txt"))
{ logger.setStream (stream); }
или
FileStream stream = new FileStream (@"c:\mylog.txt");
logger.setStream (stream);
stream.Dispose();
Шаблон Одноразовые не ссылается на количество ресурсов. Теперь разработчик должен осознавать, кому принадлежит объект и кто отвечает за его очистку. Реальная проблема заключается в том, что когда вызывается Dispose (), нормальным поведением является недействительность всего объекта, предотвращая его использование.