在包装Interop COM对象时,如何在c#中实现dispose模式?

Sam*_*Sam 5 c# interop dispose

我的类包含来自Interop的对象,并在其上调用一个方法,使其分配内容.它还公开了一个释放这些东西的方法,所以我希望我应该在Dispose()中调用它:

class MyClass : IDisposable
{
    private DllName.ComClassName comInstance;

    void SomeMethod()
    {
        comInstance = new DllName.ComClassName();
        comInstance.AllocStuff();
    }

    public void Dispose()
    {
        comInstance.FreeThatStuff();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我应该扩展所有这些以遵循Dispose模式.我没有其他一次性或非托管资源可以发布,所以假设comInstance被管理(不是Interop所做的那样,将非托管包装到托管?),我认为该模式解决了:

public void Dispose()
{
    if (comInstance != null)
    {
        comInstance.FreeStuff();
        comInstance = null;
    }
}
Run Code Online (Sandbox Code Playgroud)

哪个泄漏除非我在MyClass的实例上显式调用Dispose(),这会使Dispose模式有缺陷?那么这是否意味着comInstance必须是非托管的,并且模式解析为:

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

~MyClass()
{
    DisposeComInstance();
}

private void DisposeComInstance()
{
    if (comInstance != null)
    {
        comInstance.FreeStuff();
        comInstance = null;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

  1. 为了避免使用完整的模式使我的班级混乱,我可以封闭我的班级吗?
  2. 我怎么知道ComClassName(通常是任何类)是不受管理的?

use*_*116 2

看起来你已经快把它钉牢了。我会回到这样的模式,其中您有一个受保护的虚拟处置,它采用一个布尔参数来指示是否应处置托管项目。这样,后面的人就会继续正确地实现 IDisposable

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

~MyClass()
{
    this.Dispose(false);
}

protected virtual void Dispose(bool disposing)
{
    // if (disposing)
    // {
    //      // Managed
    // }

    if (comInstance != null)
    {
        comInstance.FreeStuff();
        comInstance = null;
    }

    // base.Dispose(disposing) if required
}
Run Code Online (Sandbox Code Playgroud)