代码之家  ›  专栏  ›  技术社区  ›  MatthewMartin muthu

在不需要IDisposable的类上实现IDisposable的效果如何?

  •  3
  • MatthewMartin muthu  · 技术社区  · 14 年前

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

    Label foo = new Label(); //Where this is an ASP.NET web forms label
    

    我需要在这些web窗体标签上调用dispose吗?另外,在页面生命周期的最晚阶段对这些调用Dispose安全吗?如果一个类实现了IDisposable,但实际上没有做任何事情,那么不调用dispose有什么坏处吗?

    DataSet是另一个似乎实现IDisposable的类,原因不明。

    4 回复  |  直到 14 年前
        1
  •  6
  •   Community CDub    4 年前

    其实你不需要打电话 Dispose() 在web窗体控件上 . 一、 也看到了这些警告,并试图找出如何处理它们,然后将所有控件创建打包到中 using 我测试的语句是否确实对添加到父级的控件调用了dispose。

    TestDispose.ascx.cs测试配置:

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

    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";
      }
    }
    

    如果在调试器中运行此命令,并且在 TestDispose.Dispose() 你会发现的 Dispose() 在销毁页时由父页调用。一旦我确定了这一点,我就开始添加排除的理由 Dispose() 在页的控件树中的对象上调用

    更新

    有一件事让我很困扰,那就是我在任何地方都找不到这个文件。而 ASP.Net Page Lifecycle 是一个很好的资源它没有提到打电话 Dispose() 在子控件上。

    Dispose() 通过以下层次结构调用:

    System.Web.UI.Page.AspCompatBeginProcessRequest
    -> System.Web.UI.Page.ProcessRequest
       -> System.Web.UI.Page.ProcessRequestCleanup
          -> System.Web.UI.Control.UnloadRecursive
    

    System.Web.UI.Control.UnloadRecursive Dispose() System.Web.UI.UserControl 工具 IDisposable .

    因此,不幸的是,没有实际的文档,我们目前依赖的是实现细节,而不是合同。虽然我不会因此而改变我的排除/辩护理由,但我只是想让其他读者了解这个答案。

        2
  •  3
  •   Community CDub    7 年前

    关于数据集本身,有 a question here on Stack Overflow

    我认为一个好的经验法则是:如果您知道实现不做任何事情,而且很容易处理,那么就处理它,但不要特意(比如设置Page.Unload事件处理程序)去做。但是,如果您知道它会释放非托管资源, 除非文档另有说明,否则请将其处置(ala SharePoint)。

        3
  •  1
  •   Henk Holterman    14 年前

    你必须仔细看这堂课。如果它只是一个无害的Dispose(),那么你可以忽略它。有几个类因为它们的基类而拥有它。

    反对这一推理的主要论点是:它可能在未来的版本中发生变化。不过,对于Label来说不太可能。

        4
  •  0
  •   Kirk Woll    14 年前

    是的,如果Dispose()方法不起任何作用,那么不调用Dispose将是无害的。如果您的静态分析工具实际上正在处理这些问题,那么如果您计划使用Winforms,您可能应该将其关闭。在我看来,这不是一个很好的分析,因为有很多场景中Dispose()被链接起来,并且只需要根调用(即streams/readers)。

    推荐文章