我理解的混乱。我觉得有一些简单的指导遵循:
如果你的类“拥有”到另一个对象的引用(即你的对象创建的其他物体,或给予与理解参照该对象你的对象现在“拥有”它),那么你有责任做任何必要的清理(如果有的话)
如果那个其他对象是一个.NET对象并且没有实现IDisposable接口,那么你可能不需要需要做任何事情。按照惯例,IDisposable接口是我们用来声明我们的对象是否需要清理的接口。
如果那个其他对象是一个.NET对象并实现了IDisposable接口,那么你的类也应该实现IDisposable接口。在您的Dispose方法中,只需调用另一个对象的Dispose方法即可。
如果其他对象是非托管对象或资源,那么您的类应实现终结器以确保非托管对象/资源将被清理。遵循该博客文章中介绍的指导原则,了解如何实施该指南。
下面是对您的问题的一些具体答案。
- 在某些时候,.NET只是包装Win32调用,对吧?那么,大多数.NET对象是不是非托管资源?
即使.NET对象可以包装Win32调用,因为它是一个.NET对象的术语“非托管资源”是不恰当的,因此它是由定义中的“管理资源”。 CLR处理这些对象的内存分配和垃圾收集。
- 怎么样我们有.NET包装器的COM对象 - 他们考虑了什么?
.NET包装的对象仍然是.NET对象,所以他们是“管理资源”,但请注意,必须实现自己的物/敲定逻辑。基本上,他们负责清理“非托管资源”,这样你就不必担心了。如果你正在为COM对象实现自己的包装器,那么你将负责实现必要的dispose/finalize逻辑来清理它,以便包装器的用户不必这样做。
一个管理使用的P/Invoke调用非托管代码可能会被分配非托管资源,这取决于它被调用的类。因此,它可能需要实施必要的处理/定稿逻辑来清理那些非托管资源。
是的,这些也可以从本地库被分配非托管资源,所以它也有必要对他们实施必要的析构函数/终结逻辑。
- 在C#的水平,即有现在的析构函数实现IDisposable的C++/CLI类......被他们认为是什么?
在C++/CLI中,可以选择将声明一个类如任一管理(与ref关键字)或非托管(没有ref关键字)。如果使用ref关键字声明它,那么它是一个托管类;它将被分配到托管堆上,并在垃圾收集器超出范围并且没有更多引用时被垃圾收集器清理。如果该类没有使用ref关键字声明,那么它是非托管的,必须明确清理。无论哪种情况,该类可能都分配了需要在析构函数/终结器中清理的非托管资源。
*“如果有更新的方法来解决这个问题......”*这里的问题究竟是什么? – 2012-03-30 19:38:44
管理非托管和管理对象的生命周期。如果以错误的顺序执行此操作,则可能发生死锁 – jglouie 2012-03-30 19:40:13
[文档](http://msdn.microsoft.com/library/System.IDisposable.aspx)中给出的示例有什么问题? – 2012-03-30 19:41:28