Being primarily a C++ developer the absence of RAII (Resource Acquisition Is Initialization) in Java and .NET has always bothered me. The fact that the onus of cleaning up is moved from the class writer to its consumer (by means of try finally or .NET's using construct) seems to be markedly inferior.
I see why in Java there is no support for RAII since all objects are located on the heap and the garbage collector inherently doesn't support deterministic destruction, but in .NET with the introduction of value-types (struct) we have the (seemingly) perfect candidate for RAII. A value type that's created on the stack has a well defined scope and C++ destructor semantics can be used. However the CLR does not permit a value-type to have a destructor.
My random searches found one argument that if a value-type is boxed it falls under the jurisdiction of the garbage collector and therefore its destruction becomes non-deterministic. I feel that this argument isn't strong enough, the benefits of RAII are big enough to say that a value-type with a destructor cannot be boxed (or used as a class member).
To cut a long story short my question is: are there any other reasons value types can not be used in order to introduce RAII to .NET? (or do you think my argument about RAII's obvious advantages are flawed?)
Edit: I must have not phrased the question clearly since the first four answers have missed the point. I know about Finalize and its non-deterministic characteristics, I know about the using construct and I feel these two options are inferior to RAII. using