1

I just started using the safe navigation operator in C# for the first time and I am wondering wether this is a correct use case for that operator:

public bool HasAttributes
{
    get
    {
        return this.SomeClassMember?.Attributes?.Count > 0;
    }
}

Why exactly does this code not give me a compiler error? I thought that the result would be null if for example this.Notification or this.Notification.Attributes would be null, but return null on the other hand does not work as it does not seem to implicitly convert to false. If I am not using the operator correctly here, could someone explain how I use it correctly in my use case?

Chris
  • 1,417
  • 4
  • 21
  • 53
  • 1
    What happens if you write `return null > 0;` ? – Fildor Mar 25 '20 at 15:57
  • @Fildor I get the warning "CS0464: Comparing with null of type 'int?' always produces 'false'". However, with the statement from my question I do not get that same warning. I guess this code more or less works by "accident" because of this behavior but it still does not seem like a proper solution to me. – Chris Mar 25 '20 at 15:58
  • 1
    Because it is a compiler warning. If you write `null`, the compiler already knows it's null. If you use `this.someMember?.Count` the compiler cannot know it will be null. The point is: `return this.SomeClassMember?.Attributes?.Count > 0;` does not result in `return null;`, it results in `return null > 0;` – Fildor Mar 25 '20 at 15:59
  • 2
    This behaviour is called [lifted operators](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#lifted-operators) - _"Lifted operators permit predefined and user-defined operators that operate on non-nullable value types to also be used with nullable forms of those types."_ – stuartd Mar 25 '20 at 16:00
  • Yeah, that makes sense I guess. Is it the way to go though or is there a better way to do this? – Chris Mar 25 '20 at 16:01
  • 2
    More info at https://stackoverflow.com/a/3370150/43846 – stuartd Mar 25 '20 at 16:01
  • 2
    With a reference type you could use `??` but as that isn't available for value types the compiler is helping you out here - as otherwise you'd have to wrap the whole expression with `GetValueOrDefault()` – stuartd Mar 25 '20 at 16:03
  • 1
    Well, you _could_ use the [NullObject-Pattern](https://en.wikipedia.org/wiki/Null_object_pattern#C#). But I cannot possibly know if that fits in your architecture. – Fildor Mar 25 '20 at 16:05
  • 1
    @Fildor Not really in my case, keeping it the way it is is probably the best idea. Thanks for the help! – Chris Mar 25 '20 at 16:08

0 Answers0