2

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

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

所有没有实现 Dispose 方法的类型都是非托管的吗?我问是因为“实施处置方法”(https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose)似乎暗示它仅适用于非托管资源。

4

1 回答 1

7

这是相反的方式。

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

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

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

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

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

于 2018-01-31T17:13:03.693 回答