21

With the introduction of Null-Conditional Operators in C#, for the following evaluation,

if (instance != null && instance.Val != 0)

If I rewrite it this way,

if (instance?.Val != 0)  

it will be evaluated to true if instance is a null reference; It behaves like

if (instance == null || instance.Val != 0)

So what is the right way to rewrite the evaluation using this new syntax?

Edit:

instance is a field of a big object which is deserialized from JSON. There are quite a few pieces of code like this, first check if the field is in the JSON, if it is, check if the Val property does NOT equal to a constant, only both conditions are true, do some operation.

The code itself can be refactored to make the logical flow more "making sense" as indicated by Peter in his comment, though in this question I am interested in how to use null-conditional operators with !=.

kennyzx
  • 12,845
  • 6
  • 39
  • 83
  • 2
    I'd be tempted to do something like `if ((instance?.Val ?? 0) != 0)` – ProgrammingLlama Jun 28 '17 at 04:59
  • 2
    Actually, it behaves like `instance?.Val != 0`, where since the short-circuited `null` can't possibly equal `0`, the whole expression is `true`. Frankly, there's not enough context to know what _"the right way"_ to address the expression is. It seems weird to me that both a `null` value and a zero value both lead to the same code execution block. Given that you're in that situation, there may be some even better way to approach the scenario. Or maybe, just don't try to shoehorn null-conditional in here, since all it's going to do is make the code _less_ readable. – Peter Duniho Jun 28 '17 at 05:02
  • 1
    I created a [fiddle](https://dotnetfiddle.net/kf96px) of the problem. Peter, it seems to be a guard against performing an action unless Val has a non-zero/non-null value, which doesn't seem wrong to me if you were creating something like a PATCH API method. – ProgrammingLlama Jun 28 '17 at 05:06
  • 2
    @john, thanks, I have just play with that snippet. In this case, I would stick to the old null-check, since the code becomes less readable, it outweighs the benefit of saving a few typing. – kennyzx Jun 28 '17 at 06:18

3 Answers3

13

With Null-Conditional operator returned value can always be null

if ((instance?.Val ?? 0) != 0)

If instance was null, then instance?.Val will also be null (probably int? in your case). So you should always check for nulls before comparing with anything:

if ((instance?.Val ?? 0) != 0)

This means: If instance?.Val is null (because instance is null) then return 0. Otherwise return instance.Val. Next compare this value with 0 (is not equal to).

kennyzx
  • 12,845
  • 6
  • 39
  • 83
Pablo notPicasso
  • 3,031
  • 3
  • 17
  • 22
11

You could make use of null coallescing operator:

instance?.Val ?? 0

When instance is null or instance is not null but Val is, the above expression would evaluate to 0. Otherwise the value of Val would be returned.

Christos
  • 53,228
  • 8
  • 76
  • 108
2
if ((instance?.Val).GetValueOrDefault() != 0)  

the ? conditional operator will automatically treat the .Val property as a Nullable.

Steve Py
  • 26,149
  • 3
  • 25
  • 43
  • Yes, and `(instance?.Val).GetValueOrDefault()` will be the same as `(instance?.Val ?? 0)` after compilation, where `0` is the compile-time constant also known as `default(int)`. – Jeppe Stig Nielsen Jun 28 '17 at 10:13