In all cases, when an X object refers to an IDisposable Y object as a parameter at creation time, is it correct to assume that the X object will own Y from now on and on, by calling X.dispose () will always result in a call to Y.dispose ()
I think not, and I will try to explain why.
There is a template called IDisposablePattern that looks something like this:
public class SimpleClass : IDisposable
{
private SqlConnection _connection;
private bool _disposed;
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed) { return; }
if (_connection != null)
{
_connection.Dispose();
_connection = null;
}
_disposed = true;
}
}
Note that this can be expanded to a new level when your class uses unmanaged resources such as this:
public class SimpleClass2: IDisposable
{
private SqlConnection _connection;
private bool _disposed;
private IntPtr _unmanagedResources;
public string GetDate()
{
if(_disposed) { throw new ObjectDisposedException(this.GetType().Name);}
if (_connection == null)
{
_connection = new SqlConnection("Server=.\\SQLEXPRESS;Database=master;Integrated Security=SSPI;App=IDisposablePattern");
_connection.Open();
}
if (_unmanagedResources == IntPtr.Zero)
{
_unmanagedResources = Marshal.AllocHGlobal(100 * 1024 * 1024);
}
using (var command = _connection.CreateCommand())
{
command.CommandText = "SELECT getdate()";
return command.ExecuteScalar().ToString();
}
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed) { return; }
if (disposing)
{
if (_connection != null)
{
_connection.Dispose();
_connection = null;
}
_disposed = true;
}
if (_unmanagedResources != IntPtr.Zero)
{
Marshal.FreeHGlobal(_unmanagedResources);
_unmanagedResources = IntPtr.Zero;;
}
}
~DatabaseStateImpr()
{
Dispose(false);
}
}
source
share