Where Close* is also implemented, then Dispose should always call Close as part of the dispose implementation and because we’re all cynics reflector is our friend – see reflected code snippets for SQL Data Reader and SQL Connection below.
Obviously with view of connection pooling, closing a connection doesn’t necessarily mean that the resource is free
Framework2.0 SqlConnection
public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } protected override void Dispose(bool disposing) { if (disposing) { this._userConnectionOptions = null; this._poolGroup = null; this.Close(); } this.DisposeMe(disposing); base.Dispose(disposing); }
Framework2.0, SqlDataReader
public void Dispose() { this.Dispose(true); } protected virtual void Dispose(bool disposing) { if (disposing) { this.Close(); } }
BTW whilst I’m in favour of understanding the inner working of objects that you code against, it’s my opinion that better code is explicit code, so I would be in favour of explicit close() for all instances where close() should be called, even if I know – as a developer – that close() is implicit.
I believe this also guards against future changes to the framework, in later versions.
* Close would usually be implemented because it’s (conceptually) cheaper to re-open a closed connection (for example) than allocate a new one which would also appear to be the consensus.