Почему С# не позволяет передавать переменную using в функцию как ref или out
Возможный дубликат:
Передача объекта IDisposable по ссылке вызывает ошибку?
Почему С# не позволяет передавать переменную из блока using в функцию ref или out?
Это мой код:
using (Form s = new Form())
{
doSomthing(ref s);
}
Функция заканчивается до окончания использования используемого блока, почему С# не пропускает s
как параметр ref или out?
Ответы
Ответ 1
using
переменные рассматриваются как readonly, так как любое переназначение, вероятно, является ошибкой. Поскольку ref
позволяет переназначить, это также будет проблемой. На уровне IL out
в значительной степени идентичен ref
.
Однако, я сомневаюсь, что вы нуждаетесь ref
здесь; вы уже передаете ссылку на форму, так как это класс. Для ссылочных типов основная цель ref
заключается в том, чтобы позволить вам переназначить переменную и вызвать вызывающего абонента переназначение, т.е.
void doSomething(ref Form form)
{
form = null; // the caller will see this change
}
требуется не, если вы просто разговариваете с объектом формы:
void doSomething(Form form)
{
form.Text = "abc"; // the caller will see this change even without ref
}
так как - это тот же объект формы.
Ответ 2
Оператор var в выражении using()
считается доступным только для чтения внутри блока. См. & sect; 8.13:
Локальные переменные, объявленные в получение ресурсов доступно только для чтения, и должен включать инициализатор. ошибка времени компиляции возникает, если встроенный оператор пытается изменить эти локальные переменные (по назначению или ++ и - операторы) или пройти их как параметры ref или out.
Но обратите внимание, что это относится только к переменным, объявленным как часть инструкции using, следующее является законным (просто не очень хорошая идея):
var f2 = System.IO.File.OpenText("");
using (f2)
{
f2 = null;
}
Ответ 3
Одна из причин может заключаться в том, что doSomthing
может сделать s
ссылкой на другой экземпляр Form
, чем тот, который мы создали. Это может привести к утечке ресурсов, так как блок using затем будет вызывать Dispose
в экземпляре Form
, который пришел из метода, а не тот, который был создан в блоке использования.