использование различных типов в инструкции using (C#)
Вопрос
Поскольку оператор using в C# — это всего лишь синтаксический сахар для try/finally{dispose}, почему он принимает несколько объектов, ТОЛЬКО ЕСЛИ ОНИ ОДНОГО ТИПА?
Я этого не понимаю, поскольку все, что им нужно, — это IDisposable.Если все они реализуют IDisposable, все должно быть хорошо, но это не так.
Конкретно я привык писать
using (var cmd = new SqlCommand())
{
using (cmd.Connection)
{
// code
}
}
который я сжимаю в:
using (var cmd = new SqlCommand())
using (cmd.Connection)
{
// code
}
и я хотел бы дополнительно сжать в:
using(var cmd = new SqlCommand(), var con = cmd.Connection)
{
// code
}
но я не могу.Я мог бы, как сказали бы некоторые, написать:
using((var cmd = new SqlCommand()).Connection)
{
// code
}
поскольку все, что мне нужно — это избавиться от соединения, а не от команды, но это не имеет значения.
Решение
Вы можете сделать это:
using (IDisposable cmd = new SqlCommand(), con = (cmd as SqlCommand).Connection)
{
var command = (cmd as SqlCommand);
var connection = (con as SqlConnection);
//code
}
Возможно, вас это удовлетворит.
Другие советы
Для этого нет особенно веской технической причины;мы могли бы придумать синтаксис, который позволял бы несколько объявлений неоднородных типов.Учитывая, что мы этого не сделали, а уже есть отличный, ясный, понятный и довольно лаконичный механизм объявления вложенности с использованием блоков разных типов, мы вряд ли будем добавлять новый синтаксический сахар только ради экономии нескольких нажатий клавиш.
Другие объявления переменных в C# позволяют объявлять только несколько переменных одного типа в одном операторе;Я не понимаю, почему using
заголовки должны быть разными.
Мой личный способ использования этого может отвечать всем требованиям:
private const string SQL_CONNECTION = "Your Connection String Here";
private void Test(string sqlCmd)
{
using (var cmd = new SqlCommand(sqlCmd, new SqlConnection(SQL_CONNECTION)))
{
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Connection.Close();
// Close() is not really necessary.
// Dispose will Close the connection.
}
}
Нет, это не два случая using
предложение в одну строку, но оно настолько компактно, насколько вы пытаетесь получить в своем примере.
Более того, вы можете сделать это еще более компактным и удобным для программистов, превратив строку подключения в частную собственность:
private SqlConnection OpenConnection
{
get {
var con = new SqlConnection(SQL_CONNECTION);
con.Open();
return con;
}
}
Теперь этот первый фрагмент кода выше в Test()
можно сократить до следующего:
private void Test2(string sqlCmd)
{
using (var cmd = new SqlCommand(sqlCmd, OpenConnection))
{
cmd.ExecuteNonQuery();
}
}
Это делает кодирование очень приятным.