在处理类实例时,是否需要显式地处理其所有IDisposable成员?
本文关键字:处理 IDisposable 成员 实例 是否 | 更新日期: 2023-09-27 18:05:58
我有一个类,它的属性类型为SqlConnection
。SqlConnection
实现IDisposable
。我有以下问题:
-
我的类也应该实现
IDisposable
仅仅因为它有IDisposable
类型的属性吗? -
如果是,我需要
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
时要遵循一个模式,但我的问题非常具体到上面提到的情况。
-
对
-
对
甚至存在一个代码分析规则:CA1001:拥有一次性字段的类型应该是一次性的。
类实现了IDisposable接口来处置非托管它拥有的资源。一个IDisposable类型的实例字段指示该字段拥有非托管资源。一个类声明一个IDisposable字段间接拥有一个非托管资源并且应该实现IDisposable接口。
编辑:上面的答案是总是对父类拥有的 IDisposable
成员有效。也就是说,成员的所有权对于像您这样的公共属性来说有点模糊:如果SqlConnection
实例是在您的类之外创建的,那么您的类很可能不是实际拥有该实例,但除了您之外没有人知道。
IDisposable
成员是否为父类StreamWriter
所拥有的。有很多关于它的问题,例如这个线程:有没有办法关闭一个StreamWriter而不关闭它的BaseStream?现在甚至有一个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; }
....
}
just 使用 SqlConnection
(因为它提供了"set")的方式类似于
// 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
字段或只读属性。