为什么.NET 中没有RAII? [英] Why is there no RAII in .NET?

查看:22
本文介绍了为什么.NET 中没有RAII?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

主要是 C++ 开发人员,Java 中缺少 RAII(资源获取即初始化),并且.NET 一直困扰着我.清理的责任从类编写者转移到其使用者(通过 try finally 或 .NET 的 using 构造) 似乎明显较差.

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.

我明白了为什么在 Java 中不支持 RAII,因为所有对象都位于堆上并且垃圾收集器本质上不支持确定性销毁,但在 .NET 中引入了值类型(struct) 我们有(看似)完美的 RAII 候选者.在堆栈上创建的值类型具有明确定义的范围,并且可以使用 C++ 析构函数语义.但是,CLR 不允许值类型具有析构函数.

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.

我的随机搜索发现一个论点,如果一个值类型是装箱在垃圾收集器的管辖范围内,因此其销毁变得不确定.感觉这个论点不够强,RAII的好处大到可以说带析构函数的值类型不能装箱(或作为类成员使用).

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).

长话短说,我的问题是:是否还有其他原因不能使用值类型来将 RAII 引入 .NET?(或者你认为我关于 RAII 明显优势的论点有缺陷吗?)

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?)

我一定没有清楚地表达这个问题,因为前四个答案没有抓住要点.我了解Finalize 及其非确定性特征,我了解using 结构,我觉得这两个选项不如RAII.using 是一个类的使用者必须记住的另一件事(有多少人忘记将 StreamReader 放在 using 块中?).我的问题是关于语言设计的哲学问题,为什么会是这样,是否可以改进?

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 is one more thing the consumer of a class must remember (how many people forgot to put a StreamReader in a using block?). My question is a philosophical one about the language design, why is it the way it is and can it be improved?

例如,对于通用的确定性可破坏值类型,我可以使 usinglock 关键字变得多余(可通过库类实现):

For instance with a generic deterministically destructible value-type I can make the using and lock keywords redundant (achievable by library classes):

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

<小时>

我不禁以我曾经看过但目前无法找到其出处的恰当引语结束.


I can't help but end with a apropos quotation which I once saw but can't currently find its origin.

当我冰冷的死手超出范围时,你可以接受我的确定性破坏.--匿名

You can take my deterministic destruction when my cold dead hand goes out of scope. --Anon

推荐答案

更好的标题是为什么 C#/VB 中没有 RAII".C++/CLI(托管 C++ 的流产演变)具有与 C++ 完全相同的意义的 RAII.这只是其他 CLI 语言使用的相同终结模式的语法糖(C++/CLI 的托管对象中的析构函数实际上是终结器),但它就在那里.

A better title would be "Why is there no RAII in C#/VB". C++/CLI (The evolution of the abortion that was Managed C++) has RAII in the exact same sense as C++. It's all just syntax sugar for the same finalisation pattern that the rest of the CLI languages use (Destructors in managed objects for C++/CLI are effectively finalisers), but it is there.

您可能喜欢 http://blogs.msdn.com/hsutter/archive/2004/07/31/203137.aspx

这篇关于为什么.NET 中没有RAII?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆