Pet*_*rks 2 c# dispose destructor
我知道c#中析构函数和终结符的含义和用法的不同.
但是,通常"我应该......"的回答是"不使用析构函数,而是使用MSDN中所示的dispose模式".埃里克利珀写道相当强烈反对使用析构函数不必要的.
但是,这种"模式"主张像这样编写析构函数~T() { Dispose(false); }.陈述的原因是它是一个"后备",在程序员忘记打电话的情况下调用Dispose().当然,这忽略了这样一个事实,即终结者在他们的行动中是不确定的,甚至可能永远不会运行.
因此:
如果我使用处理模式,我还应该提供析构函数吗?顺便说一下,我只处理托管资源(DataContext例如实体框架).
如果我提供了一个析构函数:如果我的类派生自一个IDisposable可能已经提供了析构函数的类,那么我是否应该提供一个析构函数呢?我认为在这种情况下永远不会写析构函数,但是文档说它无论如何都会自动调用基类的析构函数.
Eri*_*ert 18
我实际上不会回答你的两个问题,但我会就以下问题提出意见:
陈述的原因是它是一个"后备",在程序员忘记打电话的情况下调用
Dispose().
如果要求方法的调用者传递一个非空字符串,那么如果它们传递null,你完全有权抛出异常,对吗?来电者违反了合同; 这是异常行为,所以你抛出异常.你不会想,哦,来电者"忘了"传递一个有效的论点,我想我会接受糟糕的输入和士兵.这样做有效地将方法的契约从"null是不可接受的并且将产生异常"改为"null是可接受的并且被视为空字符串".
如果要求用户在完成后调用Dispose,而他们没有,那么这与呼叫者在调用方法时未能履行合同没有什么不同.调用者未能满足要求,因此崩溃他们的程序.如果析构函数遇到非处置对象,则抛出一个信息性异常.正如调用者很快就会知道将错误的参数传递给方法会受到伤害一样,他们也会知道未能处理对象也会造成伤害.
显式处理对象是必要的,也可能不是.如果有必要,请确保用户这样做.否则就是隐瞒他们的错误.
Ree*_*sey 12
如果我使用处理模式,我还应该提供析构函数吗?顺便说一下,我只处理托管资源(例如Entity Framework DataContext).
在这种情况下,没有.原因是,当您的类被GC捕获时,所有这些对象也将由GC处理.在这种情况下,没有理由添加析构函数的开销.
这是复杂性的一部分IDisposable- 根据使用情况,确实应该不仅仅是标准实现.在这种情况下,您将封装实现的资源IDisposable.因此,允许您的用户(间接)处理这些资源很重要,但您不需要处理析构函数,因为您没有直接"拥有"的非托管资源.如果您想了解更多细节,我会在IDisposable系列的第3部分中介绍这一点.
如果我提供了一个析构函数:如果我的类是从IDisposable派生的,可能已经提供了析构函数,那么我是否应该提供一个析构函数?我认为在这种情况下永远不会写析构函数,但是文档说它无论如何都会自动调用基类的析构函数.
在这种情况下,基类应该公开表单的受保护方法protected virtual void Dispose(bool disposing).您可以将资源清理逻辑放在那里,因为基类析构函数会为您处理对此方法的调用.有关详细信息,请参阅我在IDisposable上的系列文章的第2部分.
| 归档时间: |
|
| 查看次数: |
2420 次 |
| 最近记录: |