I have a class to model an external device via TCP/IP. This class creates a client, which is basically a wrapper for System.Net.Sockets.TcpClient and instances of this class are held by an application class.
according to https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose#cascade-dispose-calls if a class owns a field that implements IDisposable it should also implement IDisposable.
So in my situation, TcpClient implements IDisposable, therefore my client class has to implement IDisposable, therefore my external device class has to implement IDisposable, therefore my application class has to implement IDisposable.
Sounds cumbersome, so I´m questioning if thats the right way to do it?
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
...
}