Подтвердить что ты не робот

Почему С# не позволяет передавать переменную using в функцию как ref или out

Возможный дубликат:
Передача объекта IDisposable по ссылке вызывает ошибку?

Почему С# не позволяет передавать переменную из блока using в функцию ref или out?

Это мой код:

using (Form s = new Form())
{
    doSomthing(ref s);
}

Функция заканчивается до окончания использования используемого блока, почему С# не пропускает s как параметр ref или out?

4b9b3361

Ответ 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, который пришел из метода, а не тот, который был создан в блоке использования.