为什么使用ConditionalAccessExpression会更改扩展方法的工作方式?

Sam*_*der 4 c# extension-methods compiler-errors

我有一个看起来像这样的扩展方法:

public static bool DoesNotExist(this object toCheck)
{
  return toCheck == null;
}
Run Code Online (Sandbox Code Playgroud)

一般我这样使用它:

if(myObject.DoesNotExist())
{
}
Run Code Online (Sandbox Code Playgroud)

我有一个包含像这样的条件访问表达式的表达式

if (myObject?.MyProperty == null)
Run Code Online (Sandbox Code Playgroud)

编译器很满意.如果我那个表达式使用我的扩展方法,就像这样:

if (myObject?.MyProperty.DoesNotExist())
Run Code Online (Sandbox Code Playgroud)

然后我得到编译器错误

CS0266无法隐式转换类型'bool?' 'bool'.存在显式转换(您是否错过了演员?)

MyProperty的类型是我的域中的一些对象,而不是bool.

为什么会发生这种情况,我可以预防吗?

Jon*_*eet 8

空条件表达式总是具有可为空的返回类型 - 毕竟,null如果左侧为空,则必须具有整体结果.

所以myObject?.MyProperty.DoesNotExist()is 的类型,Nullable<bool>不能用作if语句的条件.

通过与bool常量直接比较或使用空合并运算符可以很容易地修复:

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

if (myObject?.MyProperty.DoesNotExist() ?? false)
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,如果myObject为null,则执行不会进入if语句的主体.如果您想要相反的行为,您可以使用:

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

if (myObject?.MyProperty.DoesNotExist() ?? true)
Run Code Online (Sandbox Code Playgroud)

但是,我不确定你的扩展方法实际上是否有用 - 至少在这里不行.如果您只是进行空比较,请直接执行此操作:

if (myObject?.MyProperty == null)
Run Code Online (Sandbox Code Playgroud)

这将进入体内if的语句,如果任一 myObject为空, myObject.MyProperty为空.