如何判断资源是否不受管理?

How can I tell if a resource is unmanaged?

我正在使用 Visual Studio 2017 编写 C# 应用程序。我努力处理使用 "using" 语句实例化的所有对象。如果我实例化的对象不是基于可隐式转换为 'System.IDisposable' 的类型,Visual Studio 会警告我。此示例导致 VS 显示警告 (C#):

using (uri = new System.Uri(stringVarWithPath))
{
}

是否所有不实现 Dispose 方法的类型都是非托管的?我问是因为 "Implementing a Dispose Method" (https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose) 似乎暗示它仅适用于非托管资源。

恰恰相反。

首先,您在 .NET 中使用的所有类型都是托管的。但是一些托管类型封装了非托管资源,例如Windows句柄。

封装非托管资源的类型,通常实现IDisposableIDisposable 接口允许您通过调用 Dispose() 或将它们放入 using 来显式释放这些对象持有的非托管资源。在后一种情况下,当退出 using.

的范围时,会自动调用 Dispose()

无论如何,即使未在实现它的对象上调用 Dispose(),设计良好的 classes 也应该在 Finalize() 中释放它们的非托管资源(这基本上是析构函数).但是 Finalize() 是由GC调用的,我们不知道GC调用的频率,这使得释放资源的过程具有不确定性。如果没有 IDisposable,我们将长时间持有昂贵的非托管资源,这比可能需要的要多得多。

当一个类型没有实现 IDisposable 时,表明它没有非托管资源,并且没有理由被显式处置(当然,前提是该类型设计良好) .

请注意,某些实现 IDisposable 的类型实际上并不持有任何非托管资源。例如,一个测量执行时间的class可以实现IDisposable,这样它在构造函数中保存一个时间戳,然后在Dispose中它获取当前时间戳并计算经过的时间并将其报告给一些日志记录机制。当您将这样的 class 放入 using 中时,您可以方便地测量代码块的执行时间。