Mar*_*kac 5 c# inheritance dispose idisposable socketasynceventargs
我在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.
*/
}
Run Code Online (Sandbox Code Playgroud)
所以,我想将CleanUp()方法的内容移到Dispose(bool)方法.
首先,我检查了基类的源代码 - SocketAsyncEventArgs(使用Go To Definition,因此我将元数据视为源代码).我发现,这个类实现了IDisposable接口.很好,我只需要覆盖Dispose(bool)方法,不是吗?(有关详细信息,请参阅MSDN上的IDisposable接口," IDisposable和继承层次结构 "部分).对我来说没什么新东西......不幸的是,SocketAsyncEventArgs类实现如下:
public class SocketAsyncEventArgs : EventArgs, IDisposable
{
public void Dispose();
//some other stuff here
}
Run Code Online (Sandbox Code Playgroud)
这意味着,没有办法如何覆盖Dispose(bool)方法,因为它实现为私有而不是受保护 ...... 这是什么原因?
接下来,我在MSDN上阅读有关SocketAsyncEventArgs.Dispose()方法的内容.有趣的是,它包含以下部分:
对继承者的说明
可以通过其他对象多次调用Dispose.重写Dispose(布尔值)时,请注意不要引用之前在Dispose调用中 处理过的对象.有关如何实现Dispose(Boolean)的更多信息,请参阅实现Dispose方法.
等等......什么?
当重写Dispose(布尔)时,...
我该如何覆盖Dispose(布尔)?
在这种情况下,推荐使用IDisposable接口的方法是什么?
似乎没有什么可以阻止你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);
}
}
Run Code Online (Sandbox Code Playgroud)
给出以下输出:
父母被处置了。
孩子被处置了。
编译器会警告在子类中隐藏父类的处置,因此使用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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
是的,如果您执行以下操作,这仍然有效:
using (DisposableParent p = new DisposableChild())
{
}
Run Code Online (Sandbox Code Playgroud)
但这样的事情可以打破它:
public class Program
{
public static void Main()
{
DisposableChild c = new DisposableChild();
DisposeOfIt(c);
Console.ReadKey(true);
}
public static void DisposeOfIt(DisposableParent p)
{
p.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
只打印出父母已被处置。因此,如果您使用此方法,则必须小心控制对象的生命周期。
| 归档时间: |
|
| 查看次数: |
1156 次 |
| 最近记录: |