我在C#.NET 4.0中处理一个庞大的项目。有一个从System.Net.Sockets.SocketAsyncEventArgs类继承的自定义类。如下所示:
public class SocketTaskArgs : SocketAsyncEventArgs
{
public SocketTaskArgs()
{
Completed += someEventhHandler;
}
public void CleanUp()
{
Completed -= someEventhHandler;
}
/*
There is a lot of code here that is unimportant at the moment.
*/
}
所以,我想将CleanUp()方法的内容移到Dispose(bool)方法。
首先,我检查了基类的源代码 - SocketAsyncEventArgs(使用转到定义,以便我将元数据视为源代码)。我发现,这个类实现了IDisposable接口。很好,我只需要覆盖Dispose(bool)方法,不是吗? (有关详细信息,请参阅IDisposable Interface on MSDN,“ IDisposable和继承层次结构”部分。对我来说没什么新东西......不幸的是,SocketAsyncEventArgs类实现如下:
public class SocketAsyncEventArgs : EventArgs, IDisposable
{
public void Dispose();
//some other stuff here
}
这意味着,无法如何覆盖 Dispose(bool)方法,因为它实现为私有而不是 protected 。 。这是什么原因?
接下来,我在MSDN上阅读了SocketAsyncEventArgs.Dispose()方法。有趣的是,它包含以下部分:
对继承者的说明
Dispose 可以被其他人多次调用 对象。覆盖 Dispose(布尔)时,请注意不要引用 先前已在先前调用中处置的对象 的处置即可。有关如何实现 Dispose(布尔)的更多信息, 请参阅实现Dispose方法。
等等......什么?
覆盖 Dispose(布尔)时,......
我应该如何覆盖Dispose(布尔)?
在这种情况下,推荐使用IDisposable接口的方法是什么?
答案 0 :(得分:3)
似乎没有什么能阻止你在你的孩子班级上实施IDisposable
,举个例子:
public class DisposableParent : IDisposable
{
public void Dispose()
{
Console.WriteLine("The parent was disposed.");
}
}
public class DisposableChild : DisposableParent, IDisposable
{
public new void Dispose()
{
base.Dispose();
Console.WriteLine("The child was disposed.");
}
}
public class Program
{
public static void Main()
{
using (DisposableChild c = new DisposableChild()) { }
Console.ReadKey(true);
}
}
提供以下输出:
父母被处置。
孩子被处理了。
编译器警告隐藏子类中父类的处置,因此使用new
运算符去除该警告,只需确保从子类调用基类Dispose
(并以正确的方式实施)。
对孩子的处置会变成:
public class DisposableChild : DisposableParent, IDisposable
{
private bool _disposed = false;
public new void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (!_disposed)
{
base.Dispose();
Console.WriteLine("The child was disposed.");
_disposed = true;
}
}
}
}
是的,如果您执行以下操作,这仍然有效:
using (DisposableParent p = new DisposableChild())
{
}
但是这样的事情可以打破它:
public class Program
{
public static void Main()
{
DisposableChild c = new DisposableChild();
DisposeOfIt(c);
Console.ReadKey(true);
}
public static void DisposeOfIt(DisposableParent p)
{
p.Dispose();
}
}
仅打印出父母被处置的内容。因此,如果您使用此方法,则必须小心控制对象的生命周期。