我使用Visual Studio 2017编写C#应用程序。我努力通过利用"使用"来处理我实例化的所有对象。声明。如果我实例化一个不基于可隐式转换为System.IDisposable'的类型的对象,Visual Studio会发出警告。此示例导致VS显示警告(C#):
using (uri = new System.Uri(stringVarWithPath))
{
}
所有未实施Dispose方法的类型是否都不受管理?我问因为"实施一个Dispose方法" (https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose)似乎暗示它仅适用于非托管资源。
答案 0 :(得分:6)
反过来说。
首先,管理您在.NET中使用的所有类型。但是一些托管类型封装了非托管资源,例如Windows句柄。
封装非托管资源的类型通常实现// Instantiate the EM and inject it into the DAOs
EntityManager em = emf.createEntityManager();
// ... whatever comes here - most likely: doing some CRUD operations...
。 IDisposable
接口允许您通过调用IDisposable
或将它们放入Dispose()
来显式释放这些对象持有的非托管资源。在后一种情况下,退出using
的范围时会自动调用Dispose()
。
无论如何,即使没有在实现它的对象上调用using
,精心设计的类也应该在Dispose()
(基本上是析构函数)中释放它们的非托管资源。但是GC会调用Finalize()
,而我们不知道调用GC的频率,这会释放资源的非确定性过程。如果没有Finalize()
,我们会长时间持有昂贵的非托管资源,远远超出必要的范围。
当某个类型没有实现IDisposable
时,它表明它不包含任何非托管资源,并且没有理由明确处理(当然,如果类型设计得很好)
请注意,实现IDisposable
的某些类型实际上并不包含任何非托管资源。例如,一个测量执行时间的类可以实现IDisposable
,以便在构造函数中保存时间戳,然后在IDisposable
中获取当前时间戳并计算已用时间并将其报告给某些日志记录机制。当您将这样的类放在Dispose
中时,您可以方便地测量代码块的执行时间。