Tan*_*lax 25 .net c# inheritance idisposable
我有一个父和子类都需要实现IDisposable.应该把virtual(和base.Dispose()?)电话放在哪里?当我只是覆盖Dispose(bool disposing)调用时,我觉得很奇怪,我IDisposable没有显式Dispose()函数(仅使用继承的函数)实现,但是还有其他所有功能.
我一直在做什么(微不足道):
internal class FooBase : IDisposable
{
Socket baseSocket;
private void SendNormalShutdown() { }
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private bool _disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
SendNormalShutdown();
}
baseSocket.Close();
}
}
~FooBase()
{
Dispose(false);
}
}
internal class Foo : FooBase, IDisposable
{
Socket extraSocket;
private bool _disposed = false;
protected override void Dispose(bool disposing)
{
if (!_disposed)
{
extraSocket.Close();
}
base.Dispose(disposing);
}
~Foo()
{
Dispose(false);
}
}
Run Code Online (Sandbox Code Playgroud)
Ree*_*sey 26
当我只是重写Dispose(bool disposing)调用时,我觉得很奇怪,我没有显式的Dispose()函数(只使用继承的)实现IDisposable,但是还有其他的东西.
这是你不应该关注的.
当您继承IDisposable类时,基类已经为您处理了所有"Dispose模式"管道.你真的应该什么也不做,只能覆盖protected Dispose(bool)方法,并跟踪你是否已被处置(正确提升)ObjectDisposedException.
有关详细信息,请参阅我在IDisposable类中的子类化的博客文章.
此外,通常,考虑封装IDisposable类而不是子类化它是个好主意.有时候对IDisposable类进行子类化是合适的,但它们有点罕见.封装通常是更好的选择.
我总是求助于 Joe Duffy 对这种模式的深入研究。对我来说,他的版本就是福音。
http://joeduffyblog.com/2005/04/08/dg-update-dispose-finalization-and-resource-management/
首先要记住的是,大多数时候不需要终结器。它用于清除直接持有本机资源的非托管资源,即仅没有自己的终结器的资源。
这是基类子类对的示例。
// Base class
#region IDisposable Members
private bool _isDisposed;
public void Dispose()
{
this.Dispose(true);
// GC.SuppressFinalize(this); // Call after Dispose; only use if there is a finalizer.
}
protected virtual void Dispose(bool isDisposing)
{
if (!_isDisposed)
{
if (isDisposing)
{
// Clear down managed resources.
if (this.Database != null)
this.Database.Dispose();
}
_isDisposed = true;
}
}
#endregion
// Subclass
#region IDisposable Members
private bool _isDisposed;
protected override void Dispose(bool isDisposing)
{
if (!_isDisposed)
{
if (isDisposing)
{
// Clear down managed resources.
if (this.Resource != null)
this.Resource.Dispose();
}
_isDisposed = true;
}
base.Dispose(isDisposing);
}
#endregion
Run Code Online (Sandbox Code Playgroud)
请注意,子类有自己的 _isDispose 成员。另请注意对资源的空检查,因为您不希望这些块中出现任何异常。
卢克
为什么在不需要时使事情复杂化?
由于您不封装任何非托管资源,因此您无需为终结处理而烦恼。并且,您的类是内部的,这建议您在自己的程序集中控制继承层次结构。
因此,直接的方法是:
internal class FooBase : IDisposable
{
Socket baseSocket;
private void SendNormalShutdown()
{
// ...
}
private bool _disposed = false;
public virtual void Dispose()
{
if (!_disposed)
{
SendNormalShutdown();
baseSocket.Close();
_disposed = true;
}
}
}
internal class Foo : FooBase
{
Socket extraSocket;
private bool _disposed = false;
public override void Dispose()
{
if (!_disposed)
{
extraSocket.Close();
_disposed = true;
}
base.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
即使您确实拥有不受管理的资源,我也说您最好将它们封装在自己的可弃用类中,并像使用其他任何可弃置类一样使用它们;与上面的代码一样直接。
| 归档时间: |
|
| 查看次数: |
19991 次 |
| 最近记录: |