如果我的类定义了一个字段,其中字段的类型实现了处置模式,我应该始终实现处置模式吗?c#
本文关键字:字段 实现 模式 类型 我应该 定义 我的 如果 一个 | 更新日期: 2023-09-27 18:05:06
我最近在Jeffery Richter的"CLR via c# "中读到这篇文章;
重要如果一个类定义了一个字段,该字段的类型在其中实现了处理模式,类本身也应该实现处置模式。Dispose方法应该处理对象由字段指代。这允许使用类的人调用对其进行Dispose处理,从而释放对象所使用的资源本身。
在下面的例子中这是正确的吗?
public class SomeClass
{
private readonly StreamReader _reader; //a disposable class
public SomeClass(StreamReader reader)
{
_reader = reader;
}
}
虽然StreamReader是一个可丢弃类,但它的实例已经通过构造函数传入,因此它可能会在其他地方被引用,因此在SomeClass上实现IDisposable以便_reader可以被丢弃似乎是一个坏主意。Jeffery Richter的观点是否只适用于一次性类的实例在该类中实例化的类?
虽然StreamReader是一个一次性类,但它的实例已经是通过构造函数传入,因此可能是所以在SomeClass
上实现IDisposable
那得看情况。一般来说,当您拥有一次性资源时,实现IDisposable
是一条很好的经验法则。但是,如果您确实知道其他人将持有对上述资源的引用,则可以在类构造函数中创建重载,该重载显式地询问调用者是否希望您dispose:
public class SomeClass : IDisposable
{
private readonly StreamReader _reader; //a disposable class
private bool shouldDispose;
public SomeClass(StreamReader reader) : this(reader, true)
{
}
public SomeClass(StreamReader reader, bool shouldDispose)
{
_reader = reader;
this.shouldDispose = shouldDispose;
}
public void Dispose()
{
if (shouldDispose)
{
Dispose(true);
}
}
protected void Dispose(bool isDisposing)
{
if (isDisposing)
{
_reader.Dispose();
}
}
}
在任何情况下,"总是"都是不合适的。在很多情况下,这可能是正确的,也可能是错误的。下面是
public class DbSomething : IDisposable
{
private SqlConnection _connection;
public DbSomething (SqlConnection connection){
_connection = connection;
}
~DbSomething() {
Dispose(true);
}
bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
_connection.Dispose();
}
disposed = true;
}
}
现在,如果这个类实现了IDisposable并释放了连接,如果这个连接要在其他地方使用会发生什么?这个类正在修改不属于它的对象的状态。
,
public class DbSomething : IDisposable
{
private SqlConnection _connection;
public DbSomething (){
_connection = new SqlConnection();
}
//same dispose
}
这个类控制SqlConnection对象。它创造了它,它应该处理它。那么,如果将SqlConnection设置为公共以供其他事物使用,会发生什么情况呢?
public class DbSomething
{
public SqlConnection Connection;
public DbSomething (){
Connection = new SqlConnection();
}
//same dispose
}
现在我仍然默认,对象创建了它,对象应该删除它,但根据代码,这可能是不可能的。它可能只是一个工厂,用于创建一个最终需要被处置的长寿命对象,并且在此之后不再需要创建对象。在这种情况下,让创建对象处理它就成了一个问题,所以即使前两种情况看起来是好主意,偏离它们是适当的选择。
方法也可以是这样的,它甚至不持有要处置的对象的实例:
public class DbSomething
{
public SqlConnection CreateSqlConnection () => return new SqlConnection();
}