实现IDisposable对不需要它的类的影响?

Mat*_*tin 3 .net asp.net idisposable

我再次运行静态分析检查,我得到了100多个唠叨

Label foo = new Label(); //Where this is an ASP.NET web forms label
Run Code Online (Sandbox Code Playgroud)

我是否需要在这些网络表单标签上调用dispose?另外,页面生命周期的后期是否可以安全地调用Dispose?如果一个类实现了IDisposable,但实际上没有做任何事情,那么不调用dispose有什么危害吗?

(是的,我已经读过关闭连接是一件好事,使用块也是一件好事.)

DataSet是另一个似乎因为莫名其妙的原因而实现IDisposable的类.

Jos*_*hua 6

实际上,您不需要调用添加到父页面的Dispose() Web表单控件.我也看到了这些警告,并试图找出如何处理它们,然后在我测试的语句中包装所有控件创建之前,是否实际调用了一个添加到父级的控件上的dispose.using

TestDispose.ascx.cs:

public partial class TestDispose : System.Web.UI.UserControl {
  public void override Dispose() {
    // Set breakpoint here
    base.Dispose();
  }
}
Run Code Online (Sandbox Code Playgroud)

TestPage.aspx.cs:

public partial class TestPage : System.Web.UI.Page {
  public void override OnInit() {
    // test will be disposed of when the page is destroyed
    TestDispose test = new TestDispose();
    test.ID = "TestDispose";
    this.Controls.Add(test);

    // test1 will not be disposed of because it was not added
    // to the page's control tree.
    TestDispose test1 = new TestDispose();
    test1.ID = "TestDispose1";
  }
}
Run Code Online (Sandbox Code Playgroud)

如果你在调试器中使用断点运行它,TestDispose.Dispose()你会发现Dispose()在页面被销毁时由父页面调用.一旦我确定了这一点,我开始添加排除,其理由是" Dispose()在Page的控制树中调用对象".

更新

困扰我的一件事是我无法在任何地方找到它.虽然ASP.Net页面生命周期是一个很好的资源,但它没有提到调用Dispose()子控件.

但是,使用Reflector,我能够确定Dispose()通过以下层次结构调用:

System.Web.UI.Page.AspCompatBeginProcessRequest
-> System.Web.UI.Page.ProcessRequest
   -> System.Web.UI.Page.ProcessRequestCleanup
      -> System.Web.UI.Control.UnloadRecursive
Run Code Online (Sandbox Code Playgroud)

System.Web.UI.Control.UnloadRecursive将遍历每个Controls属性并最终调用Dispose()每个Control对象.从System.Web.UI.UserControlimplements实现继承的任何对象IDisposable.

所以,遗憾的是,如果没有实际的文档,我们目前依赖于实现细节而不是合同.虽然我不会因此而改变我的排除/理由,但我只是想为这个答案的其他读者揭示这一点.