Объект в выражении использования НЕ является неизменным? - PullRequest
2 голосов
/ 11 апреля 2019

В некоторых унаследованных проектах на моей работе я вижу множество операторов использования, ссылающихся на dbContext:

using (myContext dal = new myContext())
{
    dal.DoSomeDatabaseThing
}

Я считаю, что это довольно стандартно, и не вижу проблем.Однако во многих местах я вижу что-то вроде этого:

using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(...)
{
    sqlBulkCopy.DestinationTableName = myTable;
    sqlBulkCopy.BatchSize = 10000;
}

Вот уже много лет я понимаю, что объект, на который ссылается оператор using, является неизменным.Действительно, документация MSDN гласит: «Внутри блока using объект доступен только для чтения и не может быть изменен или переназначен».Тем не менее, блоки кода, подобные приведенному выше, работают нормально.

Что мне здесь не хватает?Ясное присвоение значений свойствам объекта - это изменение объекта, нет?Я говорил с лидером команды, но он казался не обеспокоенным - если это не сломано, не исправляйте это - вещь вещи.Но это меня теряет!

Есть мысли?Спасибо

Ответы [ 3 ]

4 голосов
/ 11 апреля 2019

В спецификации есть это, чтобы сказать о доступности ресурса, полученного в операторе using:

Локальные переменные, объявленные при получении ресурса, доступны только для чтения и должны включать инициализатор. Ошибка времени компиляции возникает, если встроенный оператор пытается изменить эти локальные переменные (с помощью присваивания или операторов ++ и -), взять их адрес или передать их в качестве параметров ref или out.

Примечательно, и, как указано в комментариях, это относится к самой локальной переменной, а не к объекту, на который она ссылается, что оператор using, вероятно, не может сделать неизменным сам по себе, не обращаясь к некоторым экстремумы.

Предположим, что у вашего IDisposable есть метод, который при вызове увеличивает частное поле для отслеживания использования перед удалением. Объект явно изменчив, но мутация скрыта как побочный эффект. Должна ли using попытаться предотвратить это? Я сильно сомневаюсь в этом. В C # не всегда легко добиться неизменности, тип должен быть разработан с учетом неизменяемости. Даже пометка поля readonly влияет только на то, что ссылочные типы переменных поля все еще могут быть изменены с помощью вызовов методов и установки полей или свойств.

2 голосов
/ 11 апреля 2019

Утверждение о том, что объект является неизменным внутри блока using, вводит в заблуждение, поскольку фактически оно подразумевает, что переменная является неизменной.То есть вы не можете переназначить переменную для другого экземпляра:

using (var a = new A())
{
    a = new A(); // compilation error
}

, но все еще разрешено изменять экземпляр

using (var a = new A())
{
    a.Prop = someValue;
}

Причина очевидна.Цель оператора using - убедиться, что экземпляр расположен точно в тот момент, который вы указали, и переназначение отменяет это, в то время как мутация внутреннего состояния не влияет на это.

0 голосов
/ 11 апреля 2019

Я думаю, что вы интерпретируете ИСПОЛЬЗОВАНИЕ неправильно, ИСПОЛЬЗОВАНИЕ просто обеспечивает границу объявляемых в них объектов, как только компилятор проходит мимо этого оператора, объект автоматически уничтожается, освобождая память до того, как GC вступит в игру.

(Присваивая значения, ссылки в этом случае будут в порядке.)

Некоторые ссылки здесь: Какая польза от "использования" в C #

Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...