【问题标题】:Type of conditional expression cannot be determined because there is no implicit conversion between 'int' and <null>无法确定条件表达式的类型,因为 'int' 和 <null> 之间没有隐式转换
【发布时间】:2013-08-18 02:31:41
【问题描述】:

为什么不编译?

int? number = true ? 5 : null;

无法确定条件表达式的类型,因为'int'和之间没有隐式转换

【问题讨论】:

标签: c# nullable


【解决方案1】:

规范(第 7.14 节)说,对于条件表达式 b ? x : y,存在三种可能性,xy 都具有类型某些良好条件 满足,xy 中只有一个具有类型并且满足某些良好条件,或者发生编译时错误。这里,“某些良好的条件”是指某些转换是可能的,我们将在下面详细介绍。

现在,让我们转向规范的密切相关部分:

如果xy 中只有一个具有类型,并且xy 都可以隐式转换为该类型,那么这就是条件表达式的类型。

这里的问题是在

int? number = true ? 5 : null;

只有一个条件结果具有类型。这里xint 文字,ynullnot 有一个类型null 不能隐式转换为int强>1。因此,不满足“某些好的条件”,就会出现编译时错误。

两种解决方法:

int? number = true ? (int?)5 : null;

这里我们仍然处于xy 中只有一个具有类型的情况。请注意,null still 没有类型,但编译器对此不会有任何问题,因为 (int?)5null 都可以隐式转换为 int?(第 6.1.4 节)和§6.1.5)。

另一种方式显然是:

int? number = true ? 5 : (int?)null;

但现在我们必须阅读规范中的 不同 子句才能理解为什么这样可以:

如果x 的类型为Xy 的类型为Y,那么

  • 如果存在从XY 的隐式转换(第6.1 节),但不存在从YX,则Y 是条件表达式的类型。

  • 如果存在从YX 的隐式转换(第6.1 节),但不存在从XY 的转换,则X 是条件表达式的类型。

  • 否则,无法确定表达式类型,并出现编译时错误。

这里xint 类型,yint? 类型。没有从int?int 的隐式转换,但是从intint? 的隐式转换,所以表达式的类型是int?

1:进一步注意左侧的类型在确定条件表达式的类型时会被忽略,这是一个常见的混淆来源。

【讨论】:

  • 很好地引用了规范来说明为什么会发生这种情况 - +1!
  • 另一个选项是new int?() 代替(int?)null
  • 如果您有一个可以为空的数据库字段类型,例如可以为空的 DateTime,并且您尝试将数据转换为 DateTime,而实际上需要 (DateTime?),则也是这种情况
  • 很好的解释。
【解决方案2】:

null 没有任何可识别的类型 - 它只需要一点刺激就可以让它开心:

int? number = true ? 5 : (int?)null;

【讨论】:

  • 或者你也可以int? number = true ? 5 : null as int?;
  • 很好的答案指出了这一点。不错的相关阅读:ericlippert.com/2013/05/30/what-the-meaning-of-is-is
  • 问题是不是 null 没有可识别的类型。问题是没有从nullint 的隐式转换。详情here.
  • 有趣的是int? number = true ? 5 : (int?)null;int? number = true ? (int?)5 : null;都可以编译!!刮擦,刮擦
  • 我在我的answer 中描述了确切为什么会发生这种情况。
【解决方案3】:

C# 9 中现在允许blog

目标类型 ??和?

有时是有条件的??和 ?: 表达式在分支之间没有明显的共享类型。这种情况今天失败了,但如果有两个分支都转换为的目标类型,C# 9.0 将允许它们:

Person person = student ?? customer; // Shared base type
int? result = b ? 0 : null; // nullable value type

或者你的例子:

// Allowed in C# 9.
int? number = true ? 5 : null;

【讨论】:

  • 应该发生的 +1
【解决方案4】:

正如其他人所提到的,5 是int,而null 不能隐式转换为int

以下是解决此问题的其他方法:

int? num = true ? 5 : default(int?);
int? num = true ? 5 : new int?();

int? num = true ? 5 : null as int?;
int? num = true ? 5 : (int?)null;

int? num = true ? (int?)5 : null;
int? num = true ? 5 as int? : null;

int? num = true ? new int?(5) : null;

此外,在您看到int? 的任何地方,您也可以使用Nullable&lt;int&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 2018-09-27
    • 2016-03-08
    相关资源
    最近更新 更多