Reputation: 82341
When I write the following code in C#:
SqlCeCommand command;
try
{
// The command used to affect the data
command = new SqlCeCommand
{
// init code removed for brevity
};
// Do stuff
// Do more stuff
}
finally
{
if (command != null)
command.Dispose();
}
Resharper complains on my check of command != null. It says that command may not be assigned (because it could fail some how in the constructing and still hit the try block).
So I change the declaration of command to be SqlCeCommand command = null;
and everyone is happy.
But I am left wondering what the difference is?
And why doesn't it just default to null? Meaning: How does C# benefit from not just defaulting local variables to null?
Upvotes: 11
Views: 2212
Reputation: 5968
Class field members get defaulted (value types each depending on its type, ref types to null) but local variables do not.
// Example 1:
SomeClass someObject;
if(x == y)
{
someObject = new SomeClass();
}
someObject.someMethod(); //Error since it may not execute the if statements
// Example 2
SomeClass someObject;
someObject = new SomeClass();
someObject.someMethod(); //No Error
EDIT: This was designed to avoid C++ runtime errors which was causing the program to close unexpectedly (because of null pointers).
P.S: You may not downvote me when I talk about C# specs (I didn't make C# specs, I cheer this avoidance though).
Upvotes: 0
Reputation: 7173
This has to do with C#'s goal to help ensure code correctness. In a class declaration (as opposed to with local variables), members have implicit values so that you don't have to explicitly set them in the declaration or the class constructor. In the context of a function/method, however, C# tracks whether a variable has been explicitly set, so that it can warn you about things just like what you're seeing... it's a design decision on the part of the language.
Upvotes: 3
Reputation: 268255
You can write equivalent but more compact code with using
construct that calls Dispose
for you:
using (var command = new SqlCeCommand
{
// init code removed for brevity
})
{
// Do stuff
// Do more stuff
}
You won't need to worry neither about disposing nor about checking for nullity.
Upvotes: 1
Reputation: 7274
Well if you want it to be null then you need to tell it to. This is to catch bugs. The compiler and utilities like ReSharper searches all execution paths and makes sure that variables are initialized before they are being used. This is to catch common coding mistakes. So there is no additional "not even null" value possible, it is only an analysis done by the compiler (or whatever) to help you out.
Class members are initialized to default values (e.g. null for reference types), so there you get the behavior you expect.
Upvotes: 5
Reputation: 50672
You can test for null as null is a value. Not initialized means no value so you can not test for it.
Upvotes: 0