C# 无法确定条件表达式的类型,因为';int';及<;空>;
为什么不编译C# 无法确定条件表达式的类型,因为';int';及<;空>;,c#,nullable,C#,Nullable,为什么不编译 int? number = true ? 5 : null; 无法确定条件表达式的类型,因为在“int”和之间没有隐式转换 null没有任何可识别的类型-只需轻轻一推即可: int? number = true ? 5 : (int?)null; 规范(§7.14)规定,对于条件表达式b?x:y,有三种可能,要么x和y都有一个类型并且满足某些良好条件,要么只有x和y中的一个有一个类型并且满足某些良好条件,要么发生编译时错误。这里,“某些良好条件”意味着某些转换是可能的,我们将在
int? number = true ? 5 : null;
无法确定条件表达式的类型,因为在“int”和之间没有隐式转换
null
没有任何可识别的类型-只需轻轻一推即可:
int? number = true ? 5 : (int?)null;
规范(§7.14)规定,对于条件表达式b?x:y
,有三种可能,要么x
和y
都有一个类型并且满足某些良好条件,要么只有x
和y
中的一个有一个类型并且满足某些良好条件,要么发生编译时错误。这里,“某些良好条件”意味着某些转换是可能的,我们将在下面详细介绍
现在,让我们来看看规范中的相关部分:
如果x
和y
中只有一个具有类型,并且x
和y
都可以隐式转换为该类型,则这就是条件表达式的类型
这里的问题是
int? number = true ? 5 : null;
只有一个条件结果具有类型。这里的x
是int
文本,y
是null
,它没有类型,null
不能隐式转换为int
1。因此,不满足“某些良好条件”,就会发生编译时错误
有两种解决方法:
int? number = true ? (int?)5 : null;
在这里,我们仍然是在这样的情况下,x
和y
中只有一个具有类型。请注意,null
仍然没有类型,但编译器对此不会有任何问题,因为(int?)5
和null
都可以隐式转换为int?
(§6.1.4和§6.1.5)
另一种方式显然是:
int? number = true ? 5 : (int?)null;
但现在我们必须阅读规范中的另一个条款来理解为什么这是可以的:
如果x
具有类型x
且y
具有类型y
,则
- 如果存在从
到X
的隐式转换(§6.1),而不是从Y
到Y
,则X
是条件表达式的类型Y
- 如果存在从
到Y
的隐式转换(§6.1),而不是从X
到X
,则Y
是条件表达式的类型X
- 否则,无法确定表达式类型,并发生编译时错误
x
类型为int
,y
类型为int?
。没有从int?
到int
的隐式转换,但是有从int
到int?
的隐式转换,因此表达式的类型是int?
1:进一步注意,在确定条件表达式的类型时忽略了左侧的类型,这是一个常见的混淆源。如其他人所述,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?
,您都可以在C#9
中使用Nullable
目标类型??然后呢?
有时是有条件的??和?:表达式在分支之间没有明显的共享类型。这种情况今天失败了,但如果存在两个分支都转换为的目标类型,C#9.0将允许这种情况:
或者你的例子:
// Allowed in C# 9.
int? number = true ? 5 : null;
或者你可以做
int?数字=真?5:null为int代码>很好的答案抓住了要点。相关阅读:问题不在于null
没有可识别的类型。问题是没有从null
到int
的隐式转换。细节。有趣的是int?数字=真?5:(int?)空代码>和int?数字=真?(int?)5:空代码>都编译!!Scratch,Scratch我在我的文章中详细介绍了为什么会发生这种情况。很好地引用了规范来说明为什么会发生这种情况-+1!另一个选项是newint?()
代替(int?)null
。如果您有一个可为空的数据库字段类型,例如一个可为空的DateTime,并且您尝试将数据强制转换到DateTime
,而实际上需要(DateTime?
,这是一个很好的解释。最好的解释和示例-topas应该发生+1
// Allowed in C# 9.
int? number = true ? 5 : null;