可空types和三元运算符:为什么? 10:null`被禁止?
我刚碰到一个奇怪的错误:
private bool GetBoolValue() { //Do some logic and return true or false }
然后,在另一种方法,像这样的东西:
int? x = GetBoolValue() ? 10 : null;
很简单,如果方法返回true,则将10赋给Nullable int
x。 否则,将null分配给可为空的 int。 但是,编译器抱怨:
错误1无法确定条件expression式的types,因为
int
和<null>
之间没有隐式转换。
我疯了吗?
编译器首先尝试评估右边的expression式:
GetBoolValue() ? 10 : null
10
是一个int
文字(不是int?
), null
是null
。 这两者之间没有隐含的转换,因此出现错误信息。
如果您将右侧expression式更改为下列之一,则编译是因为int?
之间存在隐式转换int?
和null
(#1)以及int
和int?
之间int?
(#2,#3)。
GetBoolValue() ? (int?)10 : null // #1 GetBoolValue() ? 10 : (int?)null // #2 GetBoolValue() ? 10 : default(int?) // #3
尝试这个:
int? x = GetBoolValue() ? 10 : (int?)null;
基本上发生的情况是条件运算符无法确定expression式的“返回types”。 因为编译器暗示决定10
是一个int
所以它决定这个expression式的返回types也是int
。 由于一个int
不能为null
(条件运算符的第三个操作数),它抱怨。
通过将null
转换为Nullable<int>
我们明确地告诉编译器该expression式的返回types应该是Nullable<int>
。 你可以简单地铸造10
到int?
也有同样的效果。
尝试这个:
int? result = condition ? 10 : default(int?);
顺便说一下,C#编译器的Microsoft实现实际上是以非常微妙和有趣的方式(以我的方式)获得对条件运算符的types分析错误。 我的文章是types推理的困境,第一部分 。
尝试其中之一:
int? x = GetBoolValue() ? (int?)10 : null; int? x = GetBoolValue() ? 10 : (int?)null;
问题是,三元运算符根据您的第一个参数赋值来推断types…在这种情况下,这是一个int,而不是一个可为空的int。
你可能有更好的运气:
int? x = GetBoolValue() (int?)10 : null;
int? x = GetBoolValue() ? 10 : (int?)null;
你看到这个的原因是因为在幕后你使用了Nullable,你需要告诉C#你的“null”是Nullable的一个空实例。
只需添加一个expression式。
int? x = GetBoolValue() ? 10 : (int?)null;
这是三元运算符得到混淆 – 第二个参数是一个整数,第三个参数也是一个整数,null也不适合。
这是因为编译器通过第二个和第三个操作数来确定条件操作符的types,而不是通过分配结果来确定。 编译器可以用来确定types的整型和空引用之间没有直接转换。