Dlaczego nie ma RAII w .NET?

Bycie przede wszystkim deweloperem C ++ nieobecnościRAII (Resource Acquisition Is Initialization) w Javie i .NET zawsze mi przeszkadzało. Fakt, że ciężar czyszczenia jest przenoszony z autora klasy na konsumenta (za pomocątry finally lub .NETusing skonstruować) wydaje się być znacznie gorszy.

Widzę, dlaczego w Javie nie ma obsługi RAII, ponieważ wszystkie obiekty znajdują się na stercie, a garbage collector z natury nie obsługuje deterministycznego niszczenia, ale w .NET wraz z wprowadzeniem typów wartości (struct) mamy (pozornie) idealnego kandydata na RAII. Typ wartości utworzony na stosie ma dobrze zdefiniowany zakres i można użyć semantyki destruktora C ++. Jednak CLR nie zezwala, aby typ wartości miał destruktor.

Moje przypadkowe wyszukiwania znalazły jeden argument, jeśli typem wartości jestzapakowane podlega jurysdykcji zbieracza śmieci i dlatego jego zniszczenie staje się niedeterministyczne. Uważam, że ten argument nie jest wystarczająco silny, zalety RAII są wystarczająco duże, by powiedzieć, że typu wartości z destruktorem nie można umieścić w pudełku (ani użyć jako członka klasy).

Krótko mówiąc, moje pytanie brzmi: czy są jakieś inne powody, dla których typy wartości nie mogą być użyte do wprowadzenia RAII do .NET? (czy myślisz, że mój argument o oczywistych zaletach RAII jest wadliwy?)

Edytować: Nie sformułowałem tego pytania jasno, ponieważ pierwsze cztery odpowiedzi nie trafiły w sedno. jawiedzieć oFinalize i jego niedeterministyczne cechy, wiem ousing konstrukt i uważam, że te dwie opcje są gorsze od RAII.using to jeszcze jedna rzecz, o której konsument klasy musi pamiętać (ile osób zapomniało umieścićStreamReader wusing blok?). Moje pytanie jest filozoficzne na temat projektowania języka, dlaczego tak jest i czy można je ulepszyć?

Na przykład z typowym, deterministycznie niszczącym typem wartości mogę zrobićusing ilock słowa kluczowe redundantne (osiągalne przez klasy biblioteczne):

    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();
        }
    }

Nie mogę przestać kończyć się cytatem apropos, który kiedyś widziałem, ale obecnie nie mogę znaleźć jego źródła.

Możesz zniwelować moje deterministyczne zniszczenie, gdy moja zimna martwa ręka zniknie z zasięgu. -Zaraz

questionAnswers(6)

yourAnswerToTheQuestion