Nate Barbettini
Nate Barbettini

Reputation: 53600

Why does the null-conditional operator behave differently for == and .Equals()?

I had the following code, which works fine:

var firstChild = token.First as JProperty;
bool isHref = token.Children().Count() == 1
           && firstChild?.Name == "href";

I wanted to make the string comparison case-insensitive, so I changed it to:

var firstChild = token.First as JProperty;

bool isHref = token.Children().Count() == 1
           && firstChild?.Name.Equals("href", StringComparison.OrdinalIgnoreCase);

Now the compiler is giving me an error:

Operator && cannot be applied to operands of type 'bool' and 'bool?'

I can fix the error by coalescing to false like

bool isHref = token.Children().Count() == 1
         && (firstChild?.Name.Equals("href", StringComparison.OrdinalIgnoreCase) ?? false);

But I'm curious why the compiler doesn't like the first null-conditional syntax.

Upvotes: 3

Views: 834

Answers (2)

recursive
recursive

Reputation: 86074

Let's simplify to the essentials.

string x = null, y = null;

// this is null.  b1 is bool?
var b1 = x?.Equals(y); 

// b2 is bool
// this is true, since the operator doesn't require non-null operands
var b2 = x == y;

Basically .Equals() requires a non-null object to operate on. That's different than ==, which is statically bound, not dynamically dispatched.

Upvotes: 5

Khatibzadeh
Khatibzadeh

Reputation: 470

the first expression returns null or bool

if firstChild is null then the return value will be null and it can not be used in an if condition

firstChild?.Name.Equals("href", StringComparison.OrdinalIgnoreCase)

will the same as

firstChild == null ? null : firstChild.Name.Equals("href", StringComparison.OrdinalIgnoreCase)

Upvotes: 2

Related Questions