C# 可空类型和三元运算符:为什么是`?10 : null` 被禁止?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/858080/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 04:28:10  来源:igfitidea点击:

Nullable types and the ternary operator: why is `? 10 : null` forbidden?

c#.netnullableconditional-operator

提问by BFree

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 Nullableintx. Otherwise, assign null to the nullableint. However, the compiler complains:

很简单,如果方法返回true,就给Nullable intx赋值10 。否则,将 null 分配给可为空的int。但是,编译器抱怨:

Error 1 Type of conditional expression cannot be determined because there is no implicit conversion between intand <null>.

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

Am I going nuts?

我要疯了吗?

采纳答案by LukeH

The compiler first tries to evaluate the right-hand expression:

编译器首先尝试计算右边的表达式:

GetBoolValue() ? 10 : null

The 10is an intliteral (not int?) and nullis, well, null. There's no implicit conversion between those two hence the error message.

The10是一个int字面量(不是int?),而且nullnull. 这两者之间没有隐式转换,因此出现错误消息。

If you change the right-hand expression to one of the following then it compiles because there is an implicit conversion between int?and null(#1) and between intand int?(#2, #3).

如果将右侧表达式更改为以下表达式之一,则它会编译,因为在int?null(#1) 和intint?(#2, #3)之间存在隐式转换。

GetBoolValue() ? (int?)10 : null    // #1
GetBoolValue() ? 10 : (int?)null    // #2
GetBoolValue() ? 10 : default(int?) // #3

回答by Andrew Hare

Try this:

尝试这个:

int? x = GetBoolValue() ? 10 : (int?)null;

Basically what is happening is that conditional operator is unable to determine the "return type" of the expression. Since the compiler implictitly decides that 10is an intit then decides that the return type of this expression shall be an intas well. Since an intcannot be null(the third operand of the conditional operator) it complains.

基本上发生的事情是条件运算符无法确定表达式的“返回类型”。由于编译器隐式地决定它10是一个int,然后它决定这个表达式的返回类型也应该是一个int。由于 anint不能是null(条件运算符的第三个操作数),它会抱怨。

By casting the nullto a Nullable<int>we are telling the compiler explicitly that the return type of this expression shall be a Nullable<int>. You could have just as easily casted the 10to int?as well and had the same effect.

通过null将 a强制转换为 aNullable<int>我们明确地告诉编译器这个表达式的返回类型应该是 a Nullable<int>。您也可以轻松地将10to强制转换int?并产生相同的效果。

回答by Martin Peck

int? x = GetBoolValue() ? 10 : (int?)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.

您看到这一点的原因是因为在幕后您使用的是 Nullable,并且您需要告诉 C# 您的“null”是 Nullable 的一个空实例。

回答by John Gietzen

Try one of these:

尝试以下方法之一:

int? x = GetBoolValue() ? (int?)10 : null;

int? x = GetBoolValue() ? 10 : (int?)null;

回答by Daniel Brückner

Just add an explict cast.

只需添加一个明确的演员。

int? x = GetBoolValue() ? 10 : (int?)null;

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.

混淆的是三元运算符 - 第二个参数是一个整数,第三个参数也是一个整数,而 null 不适合。

回答by Justin Niessner

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.

问题是三元运算符根据您的第一个参数分配推断类型...10 在这种情况下,它是一个 int,而不是一个可以为 null 的 int。

You might have better luck with:

你可能有更好的运气:

int? x = GetBoolValue() (int?)10 : null;

回答by Guffa

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.

这是因为编译器通过其第二个和第三个操作数来确定条件运算符的类型,而不是根据您将结果分配给什么。编译器可以用来确定类型的整数和空引用之间没有直接转换。

回答by Eric Lippert

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.

顺便说一句,C# 编译器的 Microsoft 实现实际上以一种非常微妙和有趣(对我而言)的方式错误地获取了条件运算符的类型分析。我关于它的文章是类型推断问题,第一部分

回答by Unknown

Try this:

尝试这个:

int? result = condition ? 10 : default(int?);

int? result = condition ? 10 : default(int?);