繁体   English   中英

在处理类实例时,是否需要显式处理其所有 IDisposable 成员?

[英]While disposing the class instance, do i need to dispose all its IDisposable members explicitly?

我有一个类,它具有SqlConnection类型的属性。 SqlConnection实现IDisposable 我有以下问题:

  1. 我的类是否也应该实现IDisposable仅仅因为它具有IDisposable类型的属性?

  2. 如果是,当我处理我的类的实例时,我是否需要明确地Dispose属性? 例如

    public class Helper : IDisposable { // Assume that it's ANY OTHER IDisposable type. SqlConnection is just an example. public SqlConnection SqlConnection { get; set; } public void Dispose() { if (SqlConnection!= null) { SqlConnection.Dispose(); } } }

注意:我知道在实现IDisposable需要遵循一种模式,但我的问题非常针对上述案例。

  1. 是的

  2. 是的

甚至存在一个代码分析规则: CA1001:拥有一次性字段的类型应该是一次性的

类实现 IDisposable 接口以处理它拥有的非托管资源。 IDisposable 类型的实例字段表示该字段拥有非托管资源。 声明 IDisposable 字段的类间接拥有非托管资源并应实现 IDisposable 接口。


编辑:上述答案对于父类拥有IDisposable成员始终有效。

这就是说,一个成员的所有权是公共的属性,如你有点含糊:如果SqlConnection是类的外部创建的实例,那么你的类实际拥有的情况,但没有人知道,除了你。

有一个关于IDisposable成员是否由其父类所有的有趣示例: StreamWriter 关于它有很多问题,例如参见这个线程: 有没有办法在不关闭其 BaseStream 的情况下关闭 StreamWriter?

现在甚至还有一个leaveOpen参数,因此StreamWriter不会处理其基本流。

取决于 如果您的班级创建拥有IDisposable必须处置它(因此,两个答案都是“是” )。 如果您的班级只使用IDisposable不能处置它(因此第一个答案通常是"no" ,第二个答案是"no" )。

在你的情况下,似乎Helper

  public class Helper
  {
      // Note, that you can assign any arbitrary Connection via this property
      public SqlConnection SqlConnection { get; set; }
      ....
  }

只是使用SqlConnection (因为它提供“设置”),就像

// It's not helper that owns SqlConnection
using (SqlConnection con = new SqlConnection(...)) {
  ...
  // helper just uses Connection, so helper must not dispose it
  Helper helper = new Helper() {
    SqlConnection = con; 
  };

  ...
}

所以它不能处理连接。 相反,这样的班级

public class Helper: IDisposable {
  private SqlConnection m_SqlConnection;

  // Note the absence of public "set"
  public SqlConnection SqlConnection {
    get {
      return m_SqlConnection; 
    } 
  }
  ...
}  

拥有它的SqlConnection所以它负责处理它:

using (Helper helper = new Helper(...)) {
  ...
  // it's helper that owns SqlConnection
  SqlConnection con = helper.SqlConnection;
  ...
} 

两者都可以 - 如果您的类负责成员字段的生命周期,那么它需要对该对象调用Dispose ,这意味着您的类需要实现IDisposable以便可以在正确的时间处理该成员。

但是,请注意,您可能不想为此类成员使用公共可设置属性,因为这样任何人都可以直接清除、处置、取消设置、重置该字段。 您的类需要保持对该字段的控制,这意味着它只能从类本身内部进行设置 - 理想情况下使用private readonly字段或只读属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM