System.Management

时间:2016-02-19 13:20:35

标签: c# idisposable

使用实现IDisposable的对象时,常见的模式是;

using(ManagementObject mObj = new ManagementObject())
{
    //Work with mObj
}

但是,在System.Management.ManagementObject的情况下,IDisposable已在最终父类上声明,在本例中为System.ComponentModel.Component

Dispose已实现如下(使用ILSpy提取):

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}
然而,Dispose上的

ManagementObject已实施如下:

// System.Management.ManagementObject
/// <summary>Releases all resources used by the Component.</summary>
public new void Dispose()
{
    if (this.wmiClass != null)
    {
        this.wmiClass.Dispose();
        this.wmiClass = null;
    }
    base.Dispose();
    GC.SuppressFinalize(this);
}

似乎在using块完成时,从直接实现接口的类调用Dispose;那是System.Component,因此此时不会清除wmiClass字段,因为此实现未执行。

如果我用简单的层次结构重新创建它:

public class Parent, IDisposable {

    public void Dispose(){
        System.WriteLine("Parent Disposing");
    }
}


public class Child : Parent {
    public new void Dispose()
    {
        System.WriteLine("Child Disposing");
        base.Dispose();
    }
}

并编写一个小型测试程序;

using (Child child = new Child())
{
    System.WriteLine("Do Stuff");
}

我得到了输出:Do Stuff, Parent Disposing

通常情况下,如果我们希望继承按预期工作,那么在Disposevirtual上将Parent声明为override更安全?如果我这样做,我会得到预期事件的顺序与原始示例中发生的事件(如果在直接实现接口的类上调用Dispose,这是有意义的。)

您是否有理由以这种方式实现Dispose而不是基类的虚拟调用?这会强制使用try {} finally {}模式,您可以在其中显式调用Dispose实现以获得预期结果。

0 个答案:

没有答案