C# 使用多个IDisposable字段初始化
是否有最佳实践来实现IDisposable类DisposableClass1,该类包含几个类型为DisposableClass2的IDisposable字段,其中:C# 使用多个IDisposable字段初始化,c#,C#,是否有最佳实践来实现IDisposable类DisposableClass1,该类包含几个类型为DisposableClass2的IDisposable字段,其中: 构造函数DisposableClass2中可能存在的异常 DisposableClass2的Dispose方法中可能存在的异常 我们无法修改DisposableClass2 我写了一些代码来显示这种情况,但对我来说,它看起来很难看。有什么办法可以改进吗 public class DisposableClass1 : IDisposa
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方法中遇到异常,我不想等待垃圾收集器处理。现在可以了,还是我可以做得更好?