views:

204

answers:

7

Is there a reason to check for null in the last using? Seems to me like it's most likely not gonna be needed?

using (var connection = new SqlConnection(connectionString))
{
using (var command = new SqlCommand(commandString, connection))
{
    using (var reader = command.ExecuteReader())
    {
      if (reader != null) {
         // Use the reader
      }
    }
   }
}

EDIT:

Should i close reader.Close() and connection.Close() inside the using if i use it like that:

            using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetailsDZP))
            using (var sqlWrite = new SqlCommand(preparedCommand, varConnection)) {
                 while (sqlWrite.Read()) {
                  //something to do.
                 }
                 sqlWrite.Close();
                 varConnection.Close();
            }




    public static SqlConnection sqlConnectOneTime(string varSqlConnectionDetails) {
        SqlConnection sqlConnection = new SqlConnection(varSqlConnectionDetails);
        sqlConnect(sqlConnection);
        if (sqlConnection.State == ConnectionState.Open) {
            return sqlConnection;
        }
        return null;
    } 

Is using of close necessary in following example or i can skip those two? sqlWrite.Close(); varConnection.Close();

With regards,

MadBoy

+2  A: 

No. Why would you do that? The documentation doesn't suggest that it might be null. What would you do if it was null, anyway? Try it again?

mquander
+4  A: 

No, this is not necessary.

But that follows from the definition of ExecuteReader, it is not related to the using clause. ExecuteReader either returns a (non-null) DataReader object or it throws an exception.
The expresion in the if statement will always be true (if it is reached).

And by leaving out the if and all the superfluous brace-pairs you can make this much easier to read:

using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(commandString, connection))
using (var reader = command.ExecuteReader())
{
    // Use the reader
}
Henk Holterman
That's the assumption but since it is possible for the reader to be null why avoid the check?
Cory Charlton
@Cory, how can the reader be null? That's not how I read the specs.
Henk Holterman
SqlDataReader reader = null; // Fine
Cory Charlton
See my answer as well. Just because ExecuteReader() is supposed to return a non-null SqlDataReader doesn't mean it always will.
Cory Charlton
So theoretically i should check each var for being null ? connection, command and reader. instead of new SqlConnection i use my own function to connect to sql public static SqlConnection sqlConnectOneTime(string varSqlConnectionDetails) { SqlConnection sqlConnection = new SqlConnection(varSqlConnectionDetails); sqlConnect(sqlConnection); if (sqlConnection.State == ConnectionState.Open) { return sqlConnection; } return null; }which returns null, maybe i should change it to return something else instead?
MadBoy
@Madboy: No you shouldn't. Your code will become a mess. I still don't buy Cory's idea that ExecuteReader could return null. But if it does your code _should_ fail with a null-ref exception.
Henk Holterman
@Henk, Which part of the specs are you refering to when you say your reading indicates it can't be null? I'm looking at the help for SqlCommand and finding it inconclusive. Personally I still do the null check so that ReSharper doesn't complain.
Mike Two
Nice to see the removal un unnecessary braces suggested, makes the code easier to work with.
Stevo3000
@Mike: you can infer this from the fact that there is no mention of when null is returned.
Henk Holterman
@Henk, I see your point. I'm not sure if I feel comfortable infering that. I guess it is really just a personal level of paranoia issue. Unfortunately there is no way for the API to clearly specifiy that it won't return a null. I am also still stuck with trying to keep ReSharper quiet in this case. I guess I could add an annotation to make it happy.
Mike Two
Mike, if you apply the same rule to the Connection and Command objects you get 3 nested usings interleaved with 3 if/else statements, and no real improvement in code quality.
Henk Holterman
@Henk, not quite true. You're constructing connection and command. ExecuteReader is the only method call. I do feel confident that the constructor will not return null, but a method call is a different story.
Mike Two
Mike, you're right. But my point remains: You should not check every time a method returns a reference. Only when it is an expected case.
Henk Holterman
Guys, can you please also let me know if it's necessary to close sql connection, sql query inside using ? varConnection.Close(); reader.Close(); before closing bracket of using?
MadBoy
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetailsDZP)) using (var sqlWrite = new SqlCommand(preparedCommand, varConnection)) {}} should i close varConnection and sqlWrite or i can leave it be?
MadBoy
@madboy, that has been asked and answered a lot here: No, `using` ensures Dispose and Dispose calls Close (or equiv).
Henk Holterman
+1  A: 

Hi, the using statements are not going to check for null for you, so if command.ExecuteReader() can return null you have to check for it explicitly, just like in your code snippet.

EDIT: Looks like in this particular case ExecuteReader() should now return null, so you can avoid it. Please remember that you need it in general case though.

Grzenio
MSDN has a better memory: http://msdn.microsoft.com/en-us/library/9kcbe65k.aspx
mquander
@mquander in this instance perhaps it's not necessary, but in the general case, `using` clauses do not guarantee that the reference is not null, just that the reference has `IDisposable.Dispose()` called at the end of the scope of the using block.
Robert Paulson
I guess that's true, if that's really what the poster was asking about.
mquander
I'm especially interested in using Using and SQL not overall approach for checking if object can be null. Resharper tends to suggest that i should check for null but if it can't be null then i can just skip that step.
MadBoy
@MadBoy: Resharper suggests you check because a SqlDataReader can be null. Regardless of what the ExecuteReader() documentation says it is a possibility and I'm not sure what you're hoping to get by not checking it?
Cory Charlton
Less code lines :-)
MadBoy
Heh :-) You're not already doing while(reader.Read()) ? .. while(reader != null -)
Cory Charlton
I wasn't but it's a good idea, but it never happened for me that SqlDataReader was null. It always threw exception of some kind if there was an error and never reached the if null check.
MadBoy
@mquander, thanks for pointing this out, I updated my reply accordingly.
Grzenio
+1  A: 

Seems like the null check is worth it simply to avoid that slim chance that the object is null. Take a look at my answer to http://stackoverflow.com/questions/2214446/how-can-i-modify-a-queue-collection-in-a-loop/2214462#2214462

In the example Queue.Dequeue() should never return a null but it does. It's an extreme case but I don't see why you wouldn't want to avoid an unhandled exception, especially if it's as easy as if (object != null)

For Henk (you can run the code yourself and get similar results):

alt text

Either way I was simply stating my opinion that just because the documentation says it will do one thing doesn't mean it always will. Not sure why I got the downvote simply because someone has a different opinion :-)

Edit: Stupid tool tip, either way you can see the processed is 9998065 and the null values encountered is 2264. If there is something fundamentally wrong with my example code I'd be interested in hearing it. I'm gonna back away from this thread now.

Cory Charlton
I'm kind of skeptical about Dequeue returning nulls, but even if it does that cannot be extended to ExecuteReader.
Henk Holterman
I post a full example code that shows it both returning a null value AND decreasing the count. Granted the documentation on Queue mentions thread safety but Dequeue() also says it returns the item, which it doesn't always.
Cory Charlton
Cory, you are still confusing Queue and DataReader.
Henk Holterman
And I took a look at that other question. You are simply demonstrating a race condition while using a Queue without locking. There is nothing wrong with DeQueue() itself.
Henk Holterman
A: 

Doesnt make much sense.

Instead of that maybe you could use

if (reader.HasRows)
{
   // Code 
}
kevchadders
+1  A: 

Since you are specifically using SqlConnection and SqlCommand - no, there is no reason for this check.

However, the ADO interfaces are so that you can plug in any other DB provider and use them via the ADO base classes (DbConnection, DbCommand etc). It seems that some providers are returning null sometimes (MySQL maybe?), which may be why the programmer inserted this. Or just because ReSharper issues a warning here? These may be reasons for this, even though it is not necessary if the providers used follow the contract.

Lucero
A: 

In this case you should not check reader for null.

But you may use Code Contracts library and use Contract.Assume (or Contract.Assert) to write your assumptions about code. In this case you can use tools for static analysis and easily remove this checks from your release builds.

Sergey Teplyakov