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

dav*_*dhq 141 c# nullable

为什么这不编译?

int? number = true ? 5 : null;
Run Code Online (Sandbox Code Playgroud)

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

jas*_*son 294

该规范(§7.14)说,对于条件表达式b ? x : y,有三种可能,要么xy都有一个类型某些良好的条件得到满足,只有一个xy有型某些良好的条件得到满足,或者编译时错误发生.在这里,"某些良好的条件"意味着某些转换是可能的,我们将在下面详细介绍.

现在,让我们转向规范的密切关系:

如果只有一个xy具有类型,都xy是隐式转换为这种类型,那么这是条件表达式的类型.

这里的问题是

int? number = true ? 5 : null;
Run Code Online (Sandbox Code Playgroud)

只有一个条件结果有一个类型.这里x是一个int文字,并且ynull其中没有具有类型null不隐式转换为一个int1.因此,不满足"某些良好条件",并发生编译时错误.

解决此两种方法:

int? number = true ? (int?)5 : null;
Run Code Online (Sandbox Code Playgroud)

在这里,我们仍然只有一个类型xy类型.请注意,null 仍然没有一个类型尚未编译器不会有这个,因为任何问题(int?)5null都隐式转换为int?(第6.1.4节和第6.1.5节).

另一种方式显然是:

int? number = true ? 5 : (int?)null;
Run Code Online (Sandbox Code Playgroud)

但现在我们必须阅读规范中的一个不同的条款,以了解为什么这是可以的:

如果x有类型X,那么y有类型Y

  • 如果一个隐式转换(第6.1节)从存在XY,但不能从YX,然后Y是条件表达式的类型.

  • 如果一个隐式转换(第6.1节)从存在YX,但不能从XY,然后X是条件表达式的类型.

  • 否则,无法确定表达式类型,并发生编译时错误.

x是类型inty类型int?.没有来自隐式转换int?int,但存在从隐式转换intint?这样的表达式的类型是int?.

1:进一步注意,在确定条件表达式的类型时忽略左侧的类型,这是混淆的常见原因.

  • 另一种选择是`new int?()`来代替`(int?)null`. (6认同)
  • 很好地引用了规范来说明为什么会发生这种情况 - +1! (4认同)

Mar*_*ell 64

null 没有任何可识别的类型 - 它只是需要一点刺激才能让它快乐:

int? number = true ? 5 : (int?)null;
Run Code Online (Sandbox Code Playgroud)

  • 或者你可以做`int?数字 = 真?5 : null 作为 int?;` (3认同)
  • 我在[answer](http://stackoverflow.com/a/18260915/45914)中确切地说明了为什么会发生这种情况。 (2认同)

WBu*_*uck 8

C# 9这现在允许的博客

目标类型 ?? 和 ?

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

Person person = student ?? customer; // Shared base type
int? result = b ? 0 : null; // nullable value type
Run Code Online (Sandbox Code Playgroud)

或者你的例子:

// Allowed in C# 9.
int? number = true ? 5 : null;
Run Code Online (Sandbox Code Playgroud)


And*_*rew 7

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;
Run Code Online (Sandbox Code Playgroud)

此外,无论您看到什么,int?都可以使用Nullable<int>它。