C# Do you need to check if something has a value and if something is greater than 0?
Asked Answered
A

6

26

Working on a project and the coder does this a lot in his checks. First, he checks if the nullable int has a value, and then he checks if it's greater than 0. Why? Why make two checks if one check (if it is greater than 0) should be sufficient? Since nulls are not greater than 0, wouldn't that be redundant?

Aerobiosis answered 18/4, 2012 at 15:16 Comment(6)
Can you post a code sample so we can see exactly what you mean?Hoagland
Oded: I guess int? foo; if (foo.HasValue && foo > 0) ...Heinrik
Are you asking from a pure syntax standpoint? Or are you concerned about /why/ he's checking for null or zero?Environmentalist
thanks everyone. Just wondering why. Because 2 checks are less efficient than one. So I'm not sure why you would do a redundant check. I think he is under the impression it is necessary to do so.Aerobiosis
In fact if your coworker is writing if (i.HasValue && i.Value > 0) then he is doing three checks. First to see if i has a value. Second, i.Value checks again to see if i has a value, because if it does not then it must throw an exception. And then finally the value is compared to zero. This is unlikely to be a performance bottleneck in your code, but still, it is good to know exactly what the code you are writing is doing.Gigigigli
What I'm getting at here is that you could in fact simply write if (i.GetValueOrDefault() > 0) -- work out the cases. If i is null then the default is zero, which is not greater than zero, so this will be false. if i is not null then we compare the value to zero. Now, I am not suggesting that you do this; writing if (i>0) is considerably more clear, and the performance difference will be measured in nanoseconds. I'm just saying that it is smart to know precisely what your tools do.Gigigigli
B
38

The code is probably redundant.

If i is int? then:

if (i.HasValue && i.Value > 0)

is equivalent to:

if (i > 0)

From MSDN:

When you perform comparisons with nullable types, if the value of one of the nullable types is null and the other is not, all comparisons evaluate to false except for != (not equal). It is important not to assume that because a particular comparison returns false, the opposite case returns true. In the following example, 10 is not greater than, less than, nor equal to null. Only num1 != num2 evaluates to true.

Beckwith answered 18/4, 2012 at 15:20 Comment(6)
Thanks. i was curious. He got upset with me when he saw I wasn't doing that redundant check. I don't know what to say to him now. (I'm an intern)Aerobiosis
@user1274649: If he's complaining that your code isn't correct then he's wrong and you can show him the MSDN page to prove it. If he's complaining that it isn't aesthetic/readable/maintable then it's a matter of taste. If he's the boss you may have to respect his decision. Either way, if he's the sort of person to get upset over such things, it might be a good idea to be tactful.Beckwith
not my boss, but I have found that not being tactful and treating him the way he treats me is effective because it actually makes me seem like I know and care what I talk about. I'll just write the code my way and watch it work just as well. haha.Aerobiosis
Normally, the opposite of i > 0 would be i <= 0. For an int? that's not true (both expressions will return false). Explicitly checking for i.HasValue points that out. Also, i != 0 will return true, even though i doesn't actually have a value.Dropout
yeah, but we are only checking whether or not that value is greater than 0. We don't need nor care to know if it is null or not. As long as it is greater than 0, it is obviously not null, we don't need to make that check. I can understand from a syntax point of view why writing it the way he did makes it easier for someone else to take that into consideration. But Mark Byers hit the nail on the head with answering my question.Aerobiosis
How about if (i is > 0)Comehither
O
4

It might be that the value for the variable has different meanings in that context.

int? someNumber = null; //might mean "there is no value"
int? someOtherNumber = 0; //might mean "the user has selected: 0"
Overwhelming answered 18/4, 2012 at 15:20 Comment(0)
R
4

The following:

class Program {
    static void Main(string[] args) {
        int? i = null;
        if (i > 0) { Console.WriteLine(">0");
        } else {     Console.WriteLine("not >0");
        }
        if (i < 0) { Console.WriteLine("<0");
        } else {     Console.WriteLine("not <0");
        }
        if (i == 0) {Console.WriteLine("==0");
        } else {     Console.WriteLine("not ==0");
        }
        Console.ReadKey();
    }
}

will output

not >0
not <0
not ==0

without throwing an exception. So the null/HasValue check in this case is redundant. There is one small difference. The following:

(i.HasValue && (i.Value == 0))

is about twice as fast as

(i == 0)

when i is null although both are so fast it's not an important difference. When i has a value, the two comparisons take about the same amount of time.

Riddell answered 18/4, 2012 at 15:28 Comment(0)
M
3

Since by default an int cannot be null and its value will be set to 0, the operator of > and < expects to work with values and not with nulls, so that's why you must first check if it's null, because it will cause an error if it is null.

You can use a logic that will always return an int, even if it's null it will 'not' return null but it will return 0 which is the default value, and by using this you can check for null + > at once.

Here are some ways to do it:

int? nullableNum = null;
int number;
number = nullableNum.GetValueOrDefault(); // will return 0 if null
number = nullableNum ?? 0;                // will return 0, or whatever you insert

If you don't know if the nullableNum will be a nullable type or not (usually not relevant in C#), then in case it turns out not to be nullable, the null operator won't work and nor the GetValueOrDefault() method, so in that case you can cast its type to a nullable int and then check:

number = ((int?)nullableNum) ?? 0
Mixologist answered 24/7, 2018 at 21:12 Comment(0)
W
2

You might find that the programmer is used to the following type of checking on reference types before dereferencing them. Given that the the Nullable HasValue is similar in concept to the null check, I guess the pattern 'stuck', even though it is redundant with nullable types.

if ((myObject != null)  && (myObject.SomeValue > 0))

...

Wildebeest answered 18/4, 2012 at 15:27 Comment(1)
that is a good theory, but it's not what is being done. checks are being done on int?, not on object then on one of the objects values. :) That makes sense though, I will keep that in mind when checking an Object's value.Aerobiosis
E
1

Null checking is generally done to prevent exceptions, or to set default values (prior to .NET 4). Checking for zero would be more of a business logic choice, depending on the circumstances.

Environmentalist answered 18/4, 2012 at 15:20 Comment(3)
we do it mostly for Ids. Ids for certain things can be null, but they cant be 0 either. So when we check to see if something exists, we check for its ID. OR if we are trying to find something, we need to search by ID so we put that check in before we do the search. I've been writing it my way whenever the check needs to be made, but I see the id.HasValue && id > 0 check everywhere.Aerobiosis
If by "ID" you mean an auto-incrementing row identity value generated inside a SQL database, then I must caution you that 0 is a perfectly valid identity value; it's just uncommon. You can seed an identity column to start incrementing from -2, insert three records, and watch 0 become a perfectly valid identity that breaks all your code which assumes 0 is invalid! Moral: Don't use null and 0 to represent the same meaning. If they're different meanings then by all means, go nuts, but make sure you're consistent in your interpretations.Chancemedley
we used 0 sometimes but its not an ID of anythingAerobiosis

© 2022 - 2024 — McMap. All rights reserved.