3

After seeing a similar question, I was wondering if the following expression ...

if (attribute != null && attribute.Description == input)

... would behave (almost) identical, to following null-propagation variant?

if (attribute?.Description == input)

So far, I could determine only following (somehow minor) differences:

  • not possible in case input is of non-nullable type
  • in case input would be itself null, behavior would be altered

Am I missing something? or are there other differences in behavior?


EDIT: in the end, the only fail-safe alternative I've found for the first snippet, would be:

if (attribute?.Description?.Equals(input) ?? false)
Community
  • 1
  • 1
Teodor Tite
  • 1,855
  • 3
  • 24
  • 31
  • 2
    `attribute` is only evaluated once in the second case, so you can never get a `NullReferenceException`. In the first case, if `attribute` is changed from non-null to null after the evaluation of the first condition but before the evaluation of the second, you'll still see an exception... – Jon Skeet Dec 05 '16 at 14:53
  • If you don't want to allow `input` to be `null` you should check that first. Then there's no difference because a nullable can be compared with a non-nullable. – Tim Schmelter Dec 05 '16 at 14:55
  • @TimSchmelter That doesn't actually help you. The point is that the two snippets *behave* differently when `input` is null, and they do so in such a way that, for the second snippet, you can't just check for it first; you would need to refactor the second snippet into something akin to the first in order for it to return the right result if `input` is allowed to be `null`. – Servy Dec 05 '16 at 14:59
  • You shouldn't be changing what a question is asking after getting an answer to that question. – Servy Dec 05 '16 at 15:07
  • @Servy Ok, sorry for that. I was thinking to keep there an updated list, where to add/remove differences. Also thought that the first wrong statement of the list could misleading others, if they won't read the answer. Thanks for the hint! – Teodor Tite Dec 05 '16 at 15:12

1 Answers1

4

The code will work if input is of a non-nullable type. There is an implicit conversion of all non-nullable types to their nullable counterparts, so input will simply be lifted to a nullable to be compared to the property value.

The only difference in behavior, as you mentioned is that, if input is null, then the second snippet has no way of differentiating between attribute being null, when it should be false, and where Description is null, where it should be true.

Oh, and this is assuming that attribute is a local variable or field. If it's a property (or is actually a more complex expression) then it could have side effects or result in a different value when computed twice, as happens in the first snippet but not the second, which is a difference in behavior.

This is all of course assuming a single threaded context. In a multithreaded context, if attribute is accessible from another thread (either because it's a field that's accessible or because it's closed over in a lambda that is exposed to another thread) then the value could be different each time it's computed, so the two snippets differ for the same reason described in the previous paragraph.

Servy
  • 202,030
  • 26
  • 332
  • 449