可空类型和三元运算符:为什么是 `? 10 : null` 禁止?
我刚刚遇到一个奇怪的错误:
private bool GetBoolValue()
{
//Do some logic and return true or false
}
然后,在另一个方法中,类似这样:
int? x = GetBoolValue() ? 10 : null;
简单,如果该方法返回 true,则将 10 分配给 Nullableint
x。 否则,将 null 分配给可空 int。 然而,编译器抱怨:
错误 1 无法确定条件表达式的类型,因为
int
和之间没有隐式转换。
我要疯了吗?
I just came across a weird error:
private bool GetBoolValue()
{
//Do some logic and return true or false
}
Then, in another method, something like this:
int? x = GetBoolValue() ? 10 : null;
Simple, if the method returns true, assign 10 to the Nullableint
x. Otherwise, assign null to the nullable int. However, the compiler complains:
Error 1 Type of conditional expression cannot be determined because there is no implicit conversion between
int
and<null>
.
Am I going nuts?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
编译器首先尝试计算右侧表达式:
10
是一个int
文字(不是int?
),并且null< /code> 是
null
。 这两者之间没有隐式转换,因此会出现错误消息。如果将右侧表达式更改为以下表达式之一,则它会编译,因为
int?
和null
(#1) 之间以及之间存在隐式转换int
和int?
(#2, #3)。The compiler first tries to evaluate the right-hand expression:
The
10
is anint
literal (notint?
) andnull
is, well,null
. There's no implicit conversion between those two hence the error message.If you change the right-hand expression to one of the following then it compiles because there is an implicit conversion between
int?
andnull
(#1) and betweenint
andint?
(#2, #3).试试这个:
基本上发生的事情是条件运算符无法确定表达式的“返回类型”。 由于编译器隐式地确定
10
是int
,因此它会确定该表达式的返回类型也应是int
。 由于int
不能为null
(条件运算符的第三个操作数),因此它会抱怨。通过将
null
转换为Nullable
,我们明确告诉编译器该表达式的返回类型应为Nullable
>。 您也可以轻松地将10
转换为int?
并获得相同的效果。Try this:
Basically what is happening is that conditional operator is unable to determine the "return type" of the expression. Since the compiler implictitly decides that
10
is anint
it then decides that the return type of this expression shall be anint
as well. Since anint
cannot benull
(the third operand of the conditional operator) it complains.By casting the
null
to aNullable<int>
we are telling the compiler explicitly that the return type of this expression shall be aNullable<int>
. You could have just as easily casted the10
toint?
as well and had the same effect.试试这个:
int? 结果=条件? 10:默认(int?);
Try this:
int? result = condition ? 10 : default(int?);
顺便说一句,C# 编译器的 Microsoft 实现实际上以一种非常微妙且有趣(对我来说)的方式错误地进行了条件运算符的类型分析。 我的文章是类型推断困境,第一部分 (2006-05-24)。
Incidentally, the Microsoft implementation of the C# compiler actually gets the type analysis of the conditional operator wrong in a very subtle and interesting (to me) way. My article on it is Type inference woes, part one (2006-05-24).
尝试以下其中一项:
Try one of these:
问题是三元运算符根据您的第一个参数分配推断类型...在本例中为 10,它是一个 int,而不是可为 null 的 int。
您可能会有更好的运气:
The problem is that the ternary operator is inferring type based on your first parameter assignment...10 in this case, which is an int, not a nullable int.
You might have better luck with:
您看到此情况的原因是因为您在幕后使用 Nullable,并且您需要告诉 C# 您的“null”是 Nullable 的 null 实例。
The reason you see this is because behind the scenes you're using Nullable and you need to tell C# that your "null" is a null instance of Nullable.
只需添加一个明确的强制转换即可。
令人困惑的是三元运算符 - 第二个参数是一个整数,第三个参数也应该是一个整数,而 null 不适合。
Just add an explict cast.
It is the ternary operator that gets confused - the second argument is an integer and so is the third argument exspected to be an integer, too, and null does not fit.
这是因为编译器通过第二个和第三个操作数来确定条件运算符的类型,而不是通过将结果分配给什么来确定。 编译器可以使用整数和空引用之间的直接转换来确定类型。
It's because the compiler determines the type of the conditional operator by its second and third operand, not by what you assign the result to. There is no direct cast between an integer and an null reference that the compiler can use to determine the type.