如果我的类定义了一个字段,其中字段的类型实现了处置模式,我应该始终实现处置模式吗?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的观点是否只适用于一次性类的实例在该类中实例化的类?

如果我的类定义了一个字段,其中字段的类型实现了处置模式,我应该始终实现处置模式吗?c#

虽然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();
}