Question

Since the C# using statement is just a syntactic sugar for try/finally{dispose} why does it accept multiple objects ONLY IF THEY ARE OF THE SAME TYPE?

I don't get it since all they need to be is IDisposable. If all of them implement IDisposable it should be fine but it isn't.

Specifically I am used to writing

using (var cmd = new SqlCommand())
{
    using (cmd.Connection)
    {
        // code
    }
}

which I compact into:

using (var cmd = new SqlCommand())
using (cmd.Connection)
{
    // code
}

and I would like to compact furthermore into:

using(var cmd = new SqlCommand(), var con = cmd.Connection)
{
    // code
}

but I can't. I could probably, some would say, write :

using((var cmd = new SqlCommand()).Connection)
{
    // code
}

since all I need to dispose is the connection and not the command but that's besides the point.

Was it helpful?

Solution

You can do this though:

using (IDisposable cmd = new SqlCommand(), con = (cmd as SqlCommand).Connection)
{
   var command = (cmd as SqlCommand);
   var connection = (con as SqlConnection);
   //code
}

Perhaps that would be satisfactory to you.

OTHER TIPS

There's no particularly good technical reason; we could have come up with a syntax that allowed multiple declarations of nonhomogeneous types. Given that we did not, and there already is a perfectly good, clear, understandable and fairly concise mechanism for declaring nested using blocks of different types, we're unlikely to add a new syntactic sugar just to save a few keystrokes.

Other variable declarations in C# only allow you to declare multiple variables of the same type in the same statement; I don't see why using headers should be different.

My personal way of using this might fit the bill:

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.
  }
}

No, this is not two instances of the using clause in one line, but it is as compact as you are trying to get in your example.

What's more, you can make this even more compact and programmer friendly by turning your connection string into a Private Property:

private SqlConnection OpenConnection
{
  get {
    var con = new SqlConnection(SQL_CONNECTION);
    con.Open();
    return con;
  }
}

Now, that first bit of code above in Test() could be shortened to the following:

private void Test2(string sqlCmd)
{
  using (var cmd = new SqlCommand(sqlCmd, OpenConnection))
  {
    cmd.ExecuteNonQuery();
  }
}

That makes coding very nice.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top