Я смотрю на (устаревшую?) Спецификацию [1] прямо сейчас.
15.13 говорит, что переменные, которые вы объявляете в части получения ресурса, доступны только для чтения.То есть:
var form = new Form1();
using (form) {
form = null;
}
работает, а
using (var form = new Form1()) {
form = null;
}
- нет.Это отвечает на часть вопроса (то есть, почему? Потому что это часть спецификации ...), но я понимаю, что это не совсем удовлетворительно.Но зачем вам это делать?
Редактировать: Подумав об этом, позвольте мне предложить возможное объяснение этого правила:
У вас есть
using (var something = new Foo()) {
something = /* whatever */
}
и компилятор позволяет это.А что если Foo понадобится много неуправляемых ресурсов (возможно, именно поэтому вы и хотели использовать using
в первую очередь)?После использования блока у вас больше нет доступа к этой ссылке.Он не был утилизирован, потому что вы переназначили something
и забыли справиться с этим самостоятельно.У вас нет гарантии, что GC работает, вообще.Или когда.Вы только что создали утечку ресурсов, которая скрыта и скрыта.
Последняя, вдохновленная ссылкой Хенка на блог Эрика Липперта, которая снова просто бросает нам спецификации:
оператор using в форме
оператор using (expression)
имеет те же два возможных расширения, но в этом случае ResourceType неявно является типом выражения времени компиляции,и переменная ресурса недоступна и невидима для встроенного оператора.
Другими словами:
var form = new Form1();
using (form) {
form = null;
}
работает, потому что это расширено до
var form = new Form1();
var invisibleThing = form;
try {
form = null;
} finally {
if (invisibleThing != null) ((IDisposable)invisibleThing).Dispose();
}
Таким образом, в этом случае тот факт, что вы не имеете никакого влияния на ссылку using
, скрыт от вас и точно такой же, как в предыдущем случае.
1: http://www.ecma -international.org/publications/standards/Ecma-334.htm