IDisposable 模式,SafeFileHandle 是非托管资源吗?

IDisposable pattern, is SafeFileHandle an unmanaged resource?

采用 Resharper 生成的 IDisposable 模式的以下片段:

[NotNull]
private SafeFileHandle Handle { get; }

#region IDisposable

private bool IsDisposed { get; set; }

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

private void ReleaseUnmanagedResources()
{
    // TODO release unmanaged resources here
}

private void Dispose(bool disposing)
{
    if (IsDisposed)
        return;

    ReleaseUnmanagedResources();

    if (disposing)
        Handle.Dispose();

    IsDisposed = true;
}

~Whatever()
{
    Dispose(false);
}

Resharper 将 SafeFileHandle 视为托管资源,但此句柄是关于非托管资源 (CreateFile)。

问题:

在处理 SafeFileHandle 时,应该将其视为托管资源还是非托管资源?

所有 C# 类 和结构都是托管资源1.

非托管资源通常由 IntPtr 或类似内容指向。您通常需要做一些非常慎重的事情才能得到一个(例如 P/Invoking 一些本机方法,或者使用 Marshal 上的其中一种方法)。

SafeFileHandleSafeHandle的子类,是专门用来包装非托管资源的类型。 SafeHandle 定义自己的终结器,必要时以合适的方式释放非托管资源。


建议 永远不要 拥有自己的非托管资源,而是 总是 使用 SafeHandle / CriticalFinalizerObject 子类来管理它们。

这避免了 P/Invoke 大陷阱之一,也意味着您不必在代码中实现完整的 IDisposable 模式:您只需要定义一个 Dispose() 方法,它在您的 SafeHandles 上调用 Dispose(),并且不需要实现终结器。

(有些人可能出于性能原因需要偏离这一点,但这样的人少之又少)


1具有 unmanaged 约束的通用类型...