Почему в .NET нет RAII?

Будучи в первую очередь разработчиком C ++, отсутствиеRAII (приобретение ресурсов является инициализацией) в Java и .NET меня всегда беспокоило. Тот факт, что ответственность за очистку переходит от автора класса к его потребителю (посредствомtry finally или .NETusing сооружатьКажется, заметно уступает.

Я понимаю, почему в Java нет поддержки RAII, поскольку все объекты расположены в куче, а сборщик мусора по своей сути не поддерживает детерминированное уничтожение, но в .NET с введением типов-значений (structУ нас есть (на первый взгляд) идеальный кандидат в RAII. Тип значения, созданный в стеке, имеет четко определенную область видимости, и можно использовать семантику деструктора C ++. Однако CLR не позволяет типу значения иметь деструктор.

Мой случайный поиск нашел один аргумент, что если тип значенияв штучной упаковке он попадает под юрисдикцию сборщика мусора и поэтому его уничтожение становится недетерминированным. Мне кажется, что этот аргумент недостаточно силен, преимущества RAII достаточно велики, чтобы сказать, что тип-значение с деструктором не может быть упакован (или использован в качестве члена класса).

Короче говоря, мой вопрос: есть ли другие причины, по которым типы значений нельзя использовать для ознакомления с RAII в .NET? (или вы думаете, что мои аргументы о очевидных преимуществах RAII неверны?)

Редактировать: Должно быть, я не четко сформулировал вопрос, так как первые четыре ответа упустили из виду. язнать околоFinalize и его недетерминированные характеристики, я знаю оusing построить, и я чувствую, что эти два варианта уступают RAII.using еще одна вещь, которую должен запомнить потребитель класса (сколько людей забыли поставитьStreamReader вusing блок?). Мой вопрос философский по поводу языкового дизайна, почему так оно и есть, и можно ли его улучшить?

Например, с помощью общего детерминированного разрушаемого типа значения я могу сделатьusing а такжеlock избыточные ключевые слова (достижимо по классам библиотеки):

    public struct Disposer<T> where T : IDisposable
    {
        T val;
        public Disposer(T t) { val = t; }
        public T Value { get { return val; } }
        ~Disposer()  // Currently illegal 
        {
            if (val != default(T))
                val.Dispose();
        }
    }

Я не могу не закончить цитатой по поводу, которую я когда-то видел, но в настоящее время не могу найти ее происхождение.

Вы можете взять мое детерминированное уничтожение, когда моя холодная мертвая рука выходит за рамки. -скоро

Ответы на вопрос(6)

Ваш ответ на вопрос