-2

I would like to refactor my SqlDataReader code, so it's using using..

SqlDataReader reader = null;
reader = xdCmd.ExecuteReader();
// use reader..

Can I use solution 1) where I declare the reader in the using and first later initialize it with a SqlDataReader, and still get the Dispose "features" using provides? Or do I need to do it as in solution 2), where the initialization happends right away, in the using? I would guess that 1) is fine, but I'm not sure.

1)

using (SqlDataReader reader = null)
{
    xdCmd.CommandText = $"select * from {tableName}";
    reader = xdCmd.ExecuteReader();
    // use reader..
}

2)

using (SqlDataReader reader = new SqlDataReader(new SqlCommand($"select * from {tableName}"), xdCon))
{
    reader = xdCmd.ExecuteReader();
    // use reader..
}
radbyx
  • 9,352
  • 21
  • 84
  • 127
  • 2
    1 just wont work, so lets cancel that out straight away, how can the compiler know what you may or may not do in the future when there isnt a reference to something – TheGeneral Mar 19 '19 at 08:23
  • Okay so 1 is not possible, I'm glad I asked then, thanks. – radbyx Mar 19 '19 at 08:27
  • 1
    https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/statements#the-using-statement – TheGeneral Mar 19 '19 at 08:27

2 Answers2

3

The C# language does not include syntax to express the concept of object "ownership" or lifetime management unlike Rust, so it's entirely up to an API's documentation to say if an object's constructor takes ownership of its arguments or not (and thus who gets to call .Dispose()). This is not something the C# compiler can determine for you. However .Dispose() implementations must be idempotent anyway so there is no harm in calling .Dispose() multiple (redundant) times.

Just follow the C# idiomatic conventions of stacked using statements:

using( SqlConnection c = new SqlConnection( connectionString ) )
using( SqlCommand cmd = c.CreateCommand() )
{
    await c.OpenAsync().ConfigureAwait(false);

    cmd.CommandText = "SELECT foo, bar FROM baz";

    using( SqlDataReader rdr = await cmd.ExecuteReaderAsync().ConfigureAwait(false) )
    {
        ...
    }
} 
Dai
  • 141,631
  • 28
  • 261
  • 374
0

for me i prefere to use the second solution it's more subtle , or you can use my example just below :

using (var sqlConnection = new SqlConnection(connection))
{
       using (var command = new SqlCommand(query, sqlConnection))
       {
            using (var read = command.ExecuteReader())
            {
                // process on your read
            }
       }
}
sayah imad
  • 1,507
  • 3
  • 16
  • 24
  • 1
    You can combine multiple `using` statements without braces so your code doesn't need extra indentation, btw. – Dai Mar 19 '19 at 08:43