c# - 如何在继承自 SocketAsyncEventArgs 的类中实现 IDisposable 接口(interface)

标签 c# inheritance dispose idisposable socketasynceventargs

我在 C# .NET 4.0 中从事一个大型项目。有一个自定义类继承自 System.Net.Sockets.SocketAsyncEventArgs类(class)。类似于以下内容:

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(使用 Go To Definition 以便我将元数据视为源代码)。我发现,这个类实现了 IDisposable 接口(interface)。很好,我只需要覆盖 Dispose(bool) 方法,不是吗? (有关详细信息,请参阅 IDisposable Interface on MSDN,“IDisposable 和继承层次结构”部分)。对我来说没什么新鲜事...不幸的是,SocketAsyncEventArgs 类的实现如下:

public class SocketAsyncEventArgs : EventArgs, IDisposable
{
    public void Dispose();

    //some other stuff here
}

这意味着,无法覆盖 Dispose(bool) 方法,因为它是作为private 而不是protected 实现的。 . 这是什么原因?

接下来,我阅读了关于 SocketAsyncEventArgs.Dispose() 的内容MSDN上的方法。有趣的是,它包含以下部分:

Notes to Inheritors

Dispose can be called multiple times by other objects. When overriding Dispose(Boolean), be careful not to reference objects that have been previously disposed of in an earlier call to Dispose. For more information about how to implement Dispose(Boolean), see Implementing a Dispose Method.

等等……什么?

When overriding Dispose(Boolean), ...

我应该如何覆盖 Dispose(Boolean)?

在这种情况下,推荐的实现 IDisposable 接口(interface)的方法是什么?

最佳答案

似乎没有什么可以阻止您在子类上实现 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);
    }
}

给出以下输出:

The parent was disposed.

The child was disposed.

编译器警告在子类中隐藏父类的处置,因此使用 new 运算符消除该警告,只需确保调用基类 Dispose 来自子类(并以正确的方式实现它)。

child 的处理会变成这样:

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

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

关于c# - 如何在继承自 SocketAsyncEventArgs 的类中实现 IDisposable 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31524394/

相关文章:

java - 泛型和继承

C++ 模板特化和子类化

C++多重继承方法重载

.net - 可以不处理 MemoryStream/StringReader 吗?

C#在列表中使用后处置对象?

c# - 如何在 asp.net 中使用 javascript 从代码后面添加 Querystring 参数?

c# - 使用 ServiceBus SubscriptionClient 时出现 RenewLock 错误

c# - 将枚举转换为键值对

wpf - 如何使UserControl在运行时自行删除(在WPF中)?

c# - 序列化 bool ?错误反射(reflect)类型