Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does using a ConditionalAccessExpression change how my extension method works?

I have an extension method that looks like this:

public static bool DoesNotExist(this object toCheck)
{
  return toCheck == null;
}

generally I use it like this:

if(myObject.DoesNotExist())
{
}

I have an expression which contains a conditional access expression like this

if (myObject?.MyProperty == null)

which the compiler is happy with. If I that expression to use my extension method, like this:

if (myObject?.MyProperty.DoesNotExist())

then I get a compiler error

CS0266 Cannot implicitly convert type 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)

The type of MyProperty is some object from my domain, not a bool.

Why does this happen, and can I prevent it?

like image 644
Sam Holder Avatar asked Feb 06 '23 14:02

Sam Holder


1 Answers

A null conditional expression always has a nullable return type - after all, it has to have an overall result of null if the left hand side is null.

So the type of myObject?.MyProperty.DoesNotExist() is Nullable<bool>, which can't be used as the condition for an if statement.

It's easy to fix either by direct comparison with a bool constant, or using the null coalescing operator:

if (myObject?.MyProperty.DoesNotExist() == true)

if (myObject?.MyProperty.DoesNotExist() ?? false)

In both of those cases, if myObject is null, execution won't enter the body of the if statement. If you want the opposite behaviour, you can use:

if (myObject?.MyProperty.DoesNotExist() != false)

if (myObject?.MyProperty.DoesNotExist() ?? true)

However, I'm not sure that your extension method is actually a useful one - at least not here. If you're just doing a null comparison, do that directly:

if (myObject?.MyProperty == null)

That will go into the body of the if statement if either myObject is null, or myObject.MyProperty is null.

like image 179
Jon Skeet Avatar answered Apr 25 '23 11:04

Jon Skeet