C# 使用多个IDisposable字段初始化

C# 使用多个IDisposable字段初始化,c#,C#,是否有最佳实践来实现IDisposable类DisposableClass1,该类包含几个类型为DisposableClass2的IDisposable字段,其中: 构造函数DisposableClass2中可能存在的异常 DisposableClass2的Dispose方法中可能存在的异常 我们无法修改DisposableClass2 我写了一些代码来显示这种情况,但对我来说,它看起来很难看。有什么办法可以改进吗 public class DisposableClass1 : IDisposa

是否有最佳实践来实现IDisposable类DisposableClass1,该类包含几个类型为DisposableClass2的IDisposable字段,其中:

  • 构造函数DisposableClass2中可能存在的异常
  • DisposableClass2的Dispose方法中可能存在的异常
  • 我们无法修改DisposableClass2
  • 我写了一些代码来显示这种情况,但对我来说,它看起来很难看。有什么办法可以改进吗

    public class DisposableClass1 : IDisposable
    {
        private List<DisposableClass2> DFields;
    
        public DisposableClass1()
        {
            DFields = new List<DisposableClass2>();
            try
            {
                for (var i = 0; i < 100; i++)
                {
                    DFields.Add(new DisposableClass2());
                }
            }
            catch (Exception)
            {
                Dispose(throwException: false);
                throw;
            }
        }
    
        public void Dispose()
        {
            Dispose(throwException: true);
        }
    
        private void Dispose(bool throwException)
        {
            var exceptions = new List<Exception>();
            foreach (var f in DFields)
            {
                try
                {
                    f.Dispose();
                }
                catch (Exception e)
                {
                    exceptions.Add(e);
                }
            }
    
            if (exceptions.Count > 0 && throwException)
                throw new AggregateException(exceptions);
        }
    }
    
    // We can't modify this class
    public class DisposableClass2 : IDisposable
    {
        public DisposableClass2()
        {
            // May throw exception.
        }
    
        public void Dispose()
        {
            // May throw exception.
        }
    
        ~DisposableClass2()
        {
            // May throw exception.
        }
    }
    
    公共类DisposableClass1:IDisposable
    {
    私人名单领域;
    公共可处置类别1()
    {
    DFields=新列表();
    尝试
    {
    对于(变量i=0;i<100;i++)
    {
    添加(新的DisposableClass2());
    }
    }
    捕获(例外)
    {
    处置(ThroweException:false);
    投掷;
    }
    }
    公共空间处置()
    {
    处置(ThroweException:true);
    }
    私有无效处置(bool throweexception)
    {
    var exceptions=新列表();
    foreach(数据字段中的var f)
    {
    尝试
    {
    f、 处置();
    }
    捕获(例外e)
    {
    例外情况。添加(e);
    }
    }
    if(exceptions.Count>0&&throweexception)
    抛出新的AggregateException(异常);
    }
    }
    //我们不能修改这个类
    公共类可处置类2:IDisposable
    {
    公共可处置类别2()
    {
    //可能引发异常。
    }
    公共空间处置()
    {
    //可能引发异常。
    }
    ~DisposableClass2()
    {
    //可能引发异常。
    }
    }
    
    构造函数中的异常不是问题,您使用的字段不会初始化。Dispose()中的异常是一个实际问题,您必须修复该类,使其无法抛出,或者永远不能捕获它。您无法假装它没有发生,并且终结器失败是一个非常严重的问题。@HansPassant在构造函数中失败是一个问题,因为存在多个可支配资源。如果其中一个失败,则需要清理所有其他成功创建的实例,并且OP类的dispose方法将不会运行,因为构造函数从未完成。处置方法中也存在同样的问题;清理一个对象时出错并不能阻止您清理其他对象。该类型没有finalizer,因此根本不需要担心,只有调用dispose的用户代码是相关的。谢谢您的评论。我在代码中做了一些修复。当然DisposableClass2应该有finalizer,我只是删除它以使代码更小。但我仍然希望尽快释放资源,如果我在构造函数或dispose方法中遇到异常,我不想等待垃圾收集器处理。现在可以了,还是我可以做得更好?