也谈IDisposable接口(四)

何种情况下类中具有封装了非托管资源对象时却不能释放呢?

举个典型的例子,在ado.net的sqlCommand和sqlconnection

按上面内容的理解SqlCommand为大致为:


  1. public class SqlCommand:IDisposable
  2.        {
  3.            private SqlConnection conn;
  4.            public SqlConnection Connection
  5.            {
  6.                get { return this.conn; }
  7.                set { this.conn = value; }
  8.            }
  9.            public SqlCommand(SqlConnection conn)
  10.            {
  11.                this.conn = conn;
  12.            }
  13.            private bool disposed = false;
  14.            public void Dispose()
  15.            {
  16.                this.Dispose(true);
  17.                GC.SuppressFinalize(this);
  18.            }
  19.            public void Dispose(bool disposing)
  20.            {
  21.                if (!disposed)
  22.                {
  23.                    if (disposing)
  24.                    {
  25.                        //
  26.                    }
  27.                    this.conn.Dispose();
  28.                }
  29.                disposed = true;
  30.            }
  31.            ~SqlCommand()
  32.            {
  33.                this.Dispose(false);
  34.            }
  35.            
  36.        }


    如果SqlCommand  在释放 this.conn对象,那这个SqlConnection将只能针对一个SqlCommand使用,即:

    1. public class UseClass
    2.     {
    3.         public UseClass()
    4.         {
    5.             System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection("连接字符串");
    6.   //conn其他操作..open啊,事务控制之类的。。。
    7.             using (System.Data.SqlClient.SqlCommand cmd1 = new System.Data.SqlClient.SqlCommand(this.conn))
    8.             {
    9.                 //cmd1...
    10.                 cmd1.ExecuteNonQuery();
    11.             }
    12.             using (System.Data.SqlClient.SqlCommand cmd2 = new System.Data.SqlClient.SqlCommand(this.conn))
    13.             {
    14.                 //cmd2....
    15.                 cmd2.ExecuteNonQuery();//在些将发生异常,因为this.conn已经在cmd1中释放.....
    16.             }
    17.         }
    18.     }

    即上面SqlCommand的Dispose(bool disposing)方法的实现是错误的,实际在SqlCommand中的Dispose并不应该释放SqlConnection对象,即

    1.  public void Dispose(bool disposing)
    2.            {
    3.                if (!disposed)
    4.                {
    5.                    if (disposing)
    6.                    {
    7.                        //
    8.                    }
    9.                    //this.conn.Dispose();
    10.                }
    11.                disposed = true;
    12.            }


    而在什么情况下可以释放,什么情况下不能释放呢?这主要涉及到类之间的关系:

    类间关系有很多种,在大的类别上可以分为两种:纵向关系、横向关系。

    纵向关系就是继承关系,它的概念非常明确,也成为OO的三个重要特征之一,这里不过多的讨论。

    横向关系较为微妙,按照UML的建议大体上可以分为四种:

      • 依赖    (Dependency)
      • 关联    (Association)
      • 聚合    (Aggregation)
      • 组合    (Composition)

    它们的强弱关系是没有异议的:依赖 < 关联 < 聚合 < 组合

     

    以上关系中继承和组合是要释放的,其他关系具不释放.

    具体的类关系详解,我将在下一篇转载文.

     

     

     

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值