如何在继承自SocketAsyncEventArgs

时间:2015-07-20 19:05:22

标签: 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.
    */
}

所以,我想将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接口的方法是什么?

1 个答案:

答案 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();
    }
}

仅打印出父母被处置的内容。因此,如果您使用此方法,则必须小心控制对象的生命周期。