Какая область действия имеет оператор using без фигурных скобок
я унаследовал следующий код:
using (var dataAccessConnection = da.GetConnection()) //no opening curly brace here
using (var command = new SqlCommand(sql, dataAccessConnection.Connection))
{
command.CommandType = CommandType.Text;
using (var sqlDataReader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (sqlDataReader.Read())
{
rueckgabe.Add(new Myclass
{
Uid = Guid.NewGuid(),
ImportVersionUid = versionUid,
MyProperty = Convert.ToInt32(sqlDataReader["MyProperty"])
});
}
}
command.Connection.Close();
dataAccessConnection.Connection.Close();
}
глядя на код я expexted открывающей фигурной скобки после оператора using.
код компилируется и делает то, что он должен делать. Приложение ведет себя непредсказуемо. В какой-то момент он не может получить доступ к серверу базы данных.
этот код имеет смысл? Имеет ли dataAccessConnection область rigth?
2 ответов
using
операторы без явных фигурных скобок применяются только к следующему оператору.
using (Idisp1)
// use it
// it's disposed
using здесь действует как одно утверждение.
using (Idisp1)
using (Idisp2)
{
}
комментатор stakx предложил форматирование, чтобы было ясно, как компилятор читает блоки using. На самом деле они обычно будут отформатированы как op:
using (Idisp1)
using (Idisp2)
{
}
, что эквивалентно это:
using (Idisp1)
{
using (Idisp2)
{
}
}
обратите внимание, что первый наверху всегда последний, чтобы избавиться. Таким образом, во всех предыдущих примерах, Idisp2.Dispose()
вызывается перед Idisp1.Dispose()
. Это не актуально во многих случаях, когда вы делаете что-то подобное, но я считаю, что вы всегда должны знать, что ваш код будет делать, и принимать обоснованное решение не заботиться.
пример этого при чтении веб-страницы:
HttpWebRequest req = ...;
using (var resp = req.GetResponse())
using (var stream = resp.GetResponseStream())
using (var reader = new StreamReader(stream))
{
TextBox1.Text = reader.ReadToEnd(); // or whatever
}
мы получаем ответ, получаем поток, получаем читатель, прочитайте поток, утилизируйте читателя, утилизируйте поток и, наконец, утилизируйте ответ.
обратите внимание, как отметил комментатор Нихил Агравал, что это языковая функция в отношении блоков, которая не является специфичной для using
ключевое слово. Например, то же самое относится к if
блоки:
if (condition)
// may or may not execute
// definitely will execute
и
if (condition1)
if (condition2)
// will execute if both are true
// definitely will execute
хотя вы никогда не должны, конечно, использовать if
заявления таким образом, как это ужасно читать, но я думал, что это поможет вы понимаете using
случае. Я лично очень хорошо с цепочки using
блоки.
спецификация языка C# (версия 5) описывает using
заявление так:
использование-statement:
using (
ресурс-приобретения)
embedded-statement
что есть:
The
using
оператор получает один или несколько ресурсов, выполняет сообщении, а затем избавляется от ресурс.
(выделено)
Итак, как же мы в конечном итоге использовать его в фигурные скобки? Потому что определение embedded-statement - это:
embedded-заявление:
блок
пустой-заявлением
выражение-заявлением
selection-statement
итерации-заявлением
прыжок-заявлением
try-заявление
проверил-заявлением
unchecked-заявление
блокировка-заявлением
использование-statement
yield-заявление
и:
The embedded-statement nonterminal используется для операторов, которые появляются в других операторах
и, наконец, мы обнаруживаем, что блок определено как:
A блок разрешает запись нескольких операторов в контекстах, где разрешен один оператор.
блок:
{
утверждение-списокopt}
таким образом, в основном, фигурные скобки всегда можно использовать, чтобы взять ситуацию, когда один оператор принимается и вместо этого имеет несколько операторов.
так получилось, что почти всегда мы хотим использовать более одного утверждения, и поэтому фигурные скобки, как правило, рассматриваются как часть if
, using
, etc заявления. Принимая во внимание, что в на самом деле, это отдельная часть языка.