在处置 class 实例时,我是否需要显式处置其所有 IDisposable 成员?
While disposing the class instance, do i need to dispose all its IDisposable members explicitly?
我有一个 class,它有一个 属性 SqlConnection
类型。 SqlConnection
实施 IDisposable
。我有以下问题:
我的 class 是否也应该实施 IDisposable
只是因为它具有 IDisposable
类型的 属性?
如果是,我是否需要 Dispose
属性 显式 当我处理我的 class?例如
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
时需要遵循一种模式,但我的问题是针对上述案例的。
两者都是 - 如果您的 class 负责成员字段的生命周期,那么它需要对该对象调用 Dispose
,这意味着您的 class 需要实现 IDisposable
以便可以在正确的时间处理成员。
但是请注意,您可能不想为这样的成员使用 public 可设置 属性,因为这样任何人都可以直接清除、处理、取消设置、重置该字段。您的 class 需要保持对该字段的控制,这意味着它只能从 class 本身内部设置 - 理想情况下使用 private readonly
字段或只读 属性.
是
是
甚至存在一个代码分析规则:CA1001: Types that own disposable fields should be disposable。
A class implements the IDisposable interface to dispose of unmanaged
resources that it owns. An instance field that is an IDisposable type
indicates that the field owns an unmanaged resource. A class that
declares an IDisposable field indirectly owns an unmanaged resource
and should implement the IDisposable interface.
编辑:以上答案始终对 parent 拥有 的 IDisposable
成员有效class.
也就是说,成员的 所有权 对于像您这样的 public 属性有点模糊:如果 SqlConnection
实例是在您的 class,您的 class 很可能 而不是 实际上拥有该实例,但除了您之外没有人知道。
关于 IDisposable
成员是否由其 parent class 拥有 有一个有趣的例子:StreamWriter
.有很多关于它的问题,例如这个线程:Is there any way to close a StreamWriter without closing its BaseStream?
现在甚至还有一个 leaveOpen
参数,因此 StreamWriter
不会释放其基本流。
它取决于。如果您的 class 创建 并且 拥有 IDisposable
它 必须处置 (所以,两个答案都是"yes")。
如果你的 class 只是 使用 IDisposable
它 一定不能处理 它(所以第一个答案通常是 "no" 第二个答案是 "no").
在你的情况下,似乎 Helper
class
public class Helper
{
// Note, that you can assign any arbitrary Connection via this property
public SqlConnection SqlConnection { get; set; }
....
}
只是使用 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;
};
...
}
所以它不能释放连接。相反,一个class那样的
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;
...
}
我有一个 class,它有一个 属性 SqlConnection
类型。 SqlConnection
实施 IDisposable
。我有以下问题:
我的 class 是否也应该实施
IDisposable
只是因为它具有IDisposable
类型的 属性?如果是,我是否需要
Dispose
属性 显式 当我处理我的 class?例如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
时需要遵循一种模式,但我的问题是针对上述案例的。
两者都是 - 如果您的 class 负责成员字段的生命周期,那么它需要对该对象调用 Dispose
,这意味着您的 class 需要实现 IDisposable
以便可以在正确的时间处理成员。
但是请注意,您可能不想为这样的成员使用 public 可设置 属性,因为这样任何人都可以直接清除、处理、取消设置、重置该字段。您的 class 需要保持对该字段的控制,这意味着它只能从 class 本身内部设置 - 理想情况下使用 private readonly
字段或只读 属性.
是
是
甚至存在一个代码分析规则:CA1001: Types that own disposable fields should be disposable。
A class implements the IDisposable interface to dispose of unmanaged resources that it owns. An instance field that is an IDisposable type indicates that the field owns an unmanaged resource. A class that declares an IDisposable field indirectly owns an unmanaged resource and should implement the IDisposable interface.
编辑:以上答案始终对 parent 拥有 的 IDisposable
成员有效class.
也就是说,成员的 所有权 对于像您这样的 public 属性有点模糊:如果 SqlConnection
实例是在您的 class,您的 class 很可能 而不是 实际上拥有该实例,但除了您之外没有人知道。
关于 IDisposable
成员是否由其 parent class 拥有 有一个有趣的例子:StreamWriter
.有很多关于它的问题,例如这个线程:Is there any way to close a StreamWriter without closing its BaseStream?
现在甚至还有一个 leaveOpen
参数,因此 StreamWriter
不会释放其基本流。
它取决于。如果您的 class 创建 并且 拥有 IDisposable
它 必须处置 (所以,两个答案都是"yes")。
如果你的 class 只是 使用 IDisposable
它 一定不能处理 它(所以第一个答案通常是 "no" 第二个答案是 "no").
在你的情况下,似乎 Helper
class
public class Helper
{
// Note, that you can assign any arbitrary Connection via this property
public SqlConnection SqlConnection { get; set; }
....
}
只是使用 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;
};
...
}
所以它不能释放连接。相反,一个class那样的
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;
...
}