ID一次性级联

IDisposable cascade

我有一个 class 可以通过 TCP/IP 为外部设备建模。此 class 创建一个客户端,它基本上是 System.Net.Sockets.TcpClient 的包装器,此 class 的实例由应用程序 class.

持有

根据 https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose#cascade-dispose-calls 如果 class 拥有实现 IDisposable 的字段,它也应该实现 IDisposable。

所以在我的情况下,TcpClient 实现了 IDisposable,因此我的客户端 class 必须实现 IDisposable,因此我的外部设备 class 必须实现 IDisposable,因此我的应用程序 class 有实施 IDisposable。

听起来很麻烦,所以我想知道这样做是否正确?

public class Client : IDisposable
{
    private TcpClient _tcpClient;
    ...

    public void Connect()
    {
        _tcpClient = new TcpClient();
        if (!_tcpClient.ConnectAsync(address, port).Wait(1000))
        ...
    }

    public void Disconnect()
    {
        _tcpClient?.Dispose();
        _tcpClient = null;
    }

    #region IDisposable
    ...
    protected virtual void Dispose(bool disposing)
    {
        if (_disposed) return;
        if (disposing)
        {
            _tcpClient?.Dispose();
            _tcpClient = null;
        }
        _disposed = true;
    }
    #endregion

    ...
}


public class SM15k : IDisposable
{
    private readonly Client _client;
    ...

    public SM15k()
    {
        _client = new Client();
    }

    #region IDisposable
    ...
    protected virtual void Dispose(bool disposing)
    {
        if (_disposed) return;
        if (disposing)
        {
            _client.Dispose();
        }
        _disposed = true;
    }
    #endregion
    ...
}


public class App : IDisposable
{
    private SM15k _SM15k;

    #region IDisposable
    ...
    protected virtual void Dispose(bool disposing)
    {
        if (_disposed) return;
        if (disposing)
        {
            _SM15k?.Dispose();
            _SM15k = null;
        }
        _disposed = true;
    }
    #endregion
    ...
}

是的,这才是正确的做法。

由于您有需要处理的依赖项,因此您必须确保将它们完全处理掉。否则,当您处理“外部设备 class”时,底部的 TcpClient 将无法正确处理,您可能会发生资源泄漏(例如,端口保持打开状态)。