Будучи в первую очередь разработчиком С++, отсутствие RAII (Инициализация приобретения ресурсов) в Java и .NET всегда беспокоило меня. Тот факт, что бремя уборки переносится от автора класса к его потребителю (с помощью try finally или .NET using construct), кажется, заметно уступает.
Я вижу, почему в Java нет поддержки для RAII, поскольку все объекты находятся в куче, а сборщик мусора по сути не поддерживает детерминированное уничтожение, а в .NET с введением типов значений (struct) у нас есть (по-видимому) идеальный кандидат для RAII. Тип значения, созданный в стеке, имеет четко определенную область и можно использовать семантику деструктора С++. Однако 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();
        }
    }
Я не могу не кончить цитатой, которую я когда-то видел, но не могу найти ее происхождения.
Вы можете принять мое детерминированное разрушение, когда моя холодная мертвая рука выходит из сферы действия. --Anon
