【问题标题】:Why does using a ConditionalAccessExpression change how my extension method works?为什么使用 ConditionalAccessExpression 会改变我的扩展方法的工作方式?
【发布时间】:2016-12-05 09:44:28
【问题描述】:

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

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

一般我是这样使用的:

if(myObject.DoesNotExist())
{
}

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

if (myObject?.MyProperty == null)

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

if (myObject?.MyProperty.DoesNotExist())

然后我得到一个编译器错误

CS0266 无法隐式转换类型“bool?” '布尔'。存在显式转换(您是否缺少演员表?)

MyProperty 的类型是我域中的某个对象,而不是布尔值。

为什么会发生这种情况,我可以阻止它吗?

【问题讨论】:

  • if ((myObject?.MyProperty).DoesNotExist()) 似乎确实有效
  • @haim770 这很有趣。谢谢你,我也许可以使用它。

标签: c# compiler-errors extension-methods


【解决方案1】:

null 条件表达式始终具有可为 null 的返回类型 - 毕竟,如果左侧为 null,它的整体结果必须为 null

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

通过与bool 常量直接比较或使用空合并运算符很容易解决:

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

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

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

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

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

但是,我不确定您的扩展方法实际上是否有用 - 至少在这里不是。如果你只是做一个空比较,直接做:

if (myObject?.MyProperty == null)

如果 either myObject 为空, myObject.MyProperty 为空,这将进入 if 语句的主体。

【讨论】:

  • 谢谢。当我正在编写一个 roslyn 分析器时出现了这个问题,该分析器提供将 ==null 更改为使用 DoesNotExist,并删除了对包含条件访问表达式的表达式的自动修复的提议,这似乎是明智之举在这里做。
  • @SamHolder:对,在这种情况下,您可能想要?? true 版本。虽然我个人还是不鼓励这样做,因为我认为在== null 版本下更容易......
  • 是的,我认为在这种情况下我会坚持使用==null 版本,除非我将整个表达式括在一组额外的括号中,因为(myObject?.MyProperty).DoesNotExist() 工作正常,正如@haim770 指出的那样出在cmets上的问题。可能只是坚持检查 null 虽然
猜你喜欢
  • 2017-01-21
  • 1970-01-01
  • 1970-01-01
  • 2019-09-23
  • 1970-01-01
  • 1970-01-01
  • 2011-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多