Я запустил ildasm, чтобы найти это:
using(Simple simp = new Simple())
{
Console.WriteLine("here");
}
генерирует код IL, который эквивалентен этому:
Simple simp = new Simple();
try
{
Console.WriteLine("here");
}
finally
{
if(simp != null)
{
simp.Dispose();
}
}
и вопрос в том, почему, черт возьми, он проверяет null в конце? Блок finally будет выполняться только в том случае, если выполняется блок try, и блок try будет выполнен только в том случае, если Simple-конструктор успешно завершит работу (I.e. не генерирует исключение), и в этом случае simp будет не нулевым. (Если есть некоторые опасения, что некоторые промежуточные шаги могут возникнуть между Простым конструктором и началом блока try, тогда это действительно будет проблемой, потому что тогда может быть выбрано исключение, которое предотвратило бы выполнение блока finally вообще.) Итак, почему, черт возьми?
Отложив (пожалуйста) аргумент о том, лучше ли использовать оператор using try-finally, я пишу свои блоки try-finally как:
Simple simp = new Simple();
try
{
Console.WriteLine("here");
}
finally
{
simp.Dispose();
simp = null; // sanity-check in case I touch simp again
// because I don't rely on all classes
// necessarily throwing
// ObjectDisposedException
}