何种情况下类中具有封装了非托管资源对象时却不能释放呢?
举个典型的例子,在ado.net的sqlCommand和sqlconnection
按上面内容的理解SqlCommand为大致为:
- public class SqlCommand:IDisposable
- {
- private SqlConnection conn;
- public SqlConnection Connection
- {
- get { return this.conn; }
- set { this.conn = value; }
- }
- public SqlCommand(SqlConnection conn)
- {
- this.conn = conn;
- }
- private bool disposed = false;
- public void Dispose()
- {
- this.Dispose(true);
- GC.SuppressFinalize(this);
- }
- public void Dispose(bool disposing)
- {
- if (!disposed)
- {
- if (disposing)
- {
- //
- }
- this.conn.Dispose();
- }
- disposed = true;
- }
- ~SqlCommand()
- {
- this.Dispose(false);
- }
- }
如果SqlCommand 在释放 this.conn对象,那这个SqlConnection将只能针对一个SqlCommand使用,即:
- public class UseClass
- {
- public UseClass()
- {
- System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection("连接字符串");
- //conn其他操作..open啊,事务控制之类的。。。
- using (System.Data.SqlClient.SqlCommand cmd1 = new System.Data.SqlClient.SqlCommand(this.conn))
- {
- //cmd1...
- cmd1.ExecuteNonQuery();
- }
- using (System.Data.SqlClient.SqlCommand cmd2 = new System.Data.SqlClient.SqlCommand(this.conn))
- {
- //cmd2....
- cmd2.ExecuteNonQuery();//在些将发生异常,因为this.conn已经在cmd1中释放.....
- }
- }
- }
即上面SqlCommand的Dispose(bool disposing)方法的实现是错误的,实际在SqlCommand中的Dispose并不应该释放SqlConnection对象,即
- public void Dispose(bool disposing)
- {
- if (!disposed)
- {
- if (disposing)
- {
- //
- }
- //this.conn.Dispose();
- }
- disposed = true;
- }
而在什么情况下可以释放,什么情况下不能释放呢?这主要涉及到类之间的关系:
类间关系有很多种,在大的类别上可以分为两种:纵向关系、横向关系。
纵向关系就是继承关系,它的概念非常明确,也成为OO的三个重要特征之一,这里不过多的讨论。
横向关系较为微妙,按照UML的建议大体上可以分为四种:
- 依赖 (Dependency)
- 关联 (Association)
- 聚合 (Aggregation)
- 组合 (Composition)
它们的强弱关系是没有异议的:依赖 < 关联 < 聚合 < 组合
以上关系中继承和组合是要释放的,其他关系具不释放.
具体的类关系详解,我将在下一篇转载文.