简体   繁体   中英

What is the best syntax for checking for null value objects in C#

It always feels wrong to me to write

if (MyObject)
    // do something

Or reversly

if (!MyObject)
    // do something

However you could argue that it is less verbose than

if (MyObject != null)
    // do something

if (MyObject == null)
    // do something

Are there any non-subjective reasons to use one over the other?

In C#, you can't do

if (MyObject) 

to check for null s. It's a compile time error (if the class doesn't have an implicit boolean conversion operator).

if (!MyObject)

is also invalid if the class doesn't overload operator ! to return a boolean value (or a value that can be implicitly casted to a boolean).

So you have to stick with obj == null and obj != null .

To summarize, the non-subjective reason is being able to compile your code!

UPDATE (story):

Once upon a time, in ancient C, there was no bool type. Zero was considered false and every non-zero value was considered true . You could write

while(1) { }

to create an infinite loop.
You could also do things like

int n  = 10;
while (n--) { }

to have a loop that executes n times. The problem with this strategy was:

int x = 10;
if (x = 0) { // bug: meant to be x == 0
}

You missed a single character and you created a bug (most modern C compilers will issue a warning on this statement, but it's valid C, nevertheless).

This is why you see code like

if (5 == variable) 

if (NULL == pObj)

in many places as it's not prone to the above mistake.

C# designers decided to require a boolean expression as the condition for if , while , etc., and not allow casting of types (unless they explicitly declare an overloaded operator, which is discouraged) to boolean to reduce the chance of errors. So things like:

object x = null;
if (x) { }

int y = 10;
if (y) { }
while (y--) { }

that are valid in C, do not compile in C# at all .
This is not a matter of style or agreement by any means.

Are there any non-subjective reasons to use one over the other?

The fact that (1) and (2) don't compile is a non-subjective reason enough to not use them.

So we are left with (3) and (4):

if (MyObject != null)
    // do something

if (MyObject == null)
    // do something

Here it depends on whether you want to do something if MyObject is null (4), or if it is not null (3). Clearly this is not a style choice. It would be ridiculous to adopt always the same "style", because then if you wanted the other condition you'd have to do:

    if (MyObject == null) // style policy
    {
        // nothing here
    }
    else
    {
        // do something
    }

Which isn't exactly what I'd call readable code.

In my mind, a bit of verbosity in this case is a good thing. That would be the case if you were allowed to do both, which isn't in fact possible, as Mehrdad points out. The "implicit" null check (ie if (MyObject) ) does not even compile in C#.

if (MyObject == null)
    // do something

This is however quite similar to the situation of checking with an integer is greater than 0. The two equivalent options here (that both compile and run fine in C but not C#, unless I'm mistaken) are:

if (myInt)
    // do something

and

if (myInt > 0)
    // do something

I always go for the second option here, purely for clarity (it can't be mistaken for a bool!), though you will quite often see the former "implicit" check in code.

In C#, an if statement requires a boolean expression.

So, in your example above using if(myObject) to test for null is actually wrong. You'd need to do the more verbose if(myObject==null) .

It depends upon personal preferences. Ideally, in C#, to check for null , the following syntax is used -

if (MyObject != null)
    //Do Something.

And if you just want to set a default value to an object if it is null, you can use the c# 3.0 ?? operator.

the code:

MyType _myObject
if (SomeObject==null)
  _myObject = defaultObjectValue
else
  _myObject = SomeObject

can be writen as

_myObject = SomeObject ?? defaultObjectValue;

which basically means that if SomeObject exists, use it, and if it does not, use the default value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM