Because you don't have to allocate the variables in a using() statement - why not use 'stacked' using statements for this?
void Dispose() { // the example in the question didn't use the full protected Dispose(bool) pattern // but most code should have if (!disposed) { if (disposing) { ... using (m_foo) using (m_bar) { // no work, using statements will check null // and call Dispose() on each object } m_bar = null; m_foo = null; }
The 'stacked' using statements are expanded like this:
using (m_foo) { using (m_bar) { /* do nothing but call Dispose */ } }
So the Dispose() calls are put in seperate finally blocks:
try { try { // do nothing but call Dispose } finally { if (m_bar != null) m_bar.Dispose(); } finally { if (m_foo != null) m_foo.Dispose(); }
I had a hard time finding a reference for this in one place. The 'stacked' using statements are found in an old Joe Duffy blog post (see section 'C# and VB Using Statement, C++ Stack Semantics'). The Joe Duffy post is referenced by many StackOverflow answers on IDisposable. I also found a recent question where stacked using statements for local variables appear to be common. I couldn't find the chaining of finally blocks anywhere but the C# language spec (section 8.13 in C# 3.0 spec), and only for multiple varaibles within a single 'using' block, which isn't exactly what I'm proposing, but if you disasemble the IL you'll find the try/finally blocks are nested. On the null check, also from the C# spec: 'If a null resource is acquired, then no call to Dispose is made, and no exception is thrown.'