可空类型和三元运算符:为什么是' ?10:零‘禁止?(复制)

时间:2022-11-30 22:24:47

This question already has an answer here:

这个问题已经有了答案:

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:

很简单,如果方法返回true,则将10赋给Nullableint x,否则将null赋给nullable int。

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

由于int和 之间没有隐式转换,因此无法确定1类型的条件表达式。

Am I going nuts?

我疯了吗?

9 个解决方案

#1


345  

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

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

GetBoolValue() ? 10 : null

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

10是一个int文字(不是int?) null是null。这两者之间没有隐含的转换,因此错误信息。

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 int and int? (#2, #3).

如果您将右边的表达式更改为下列表达式之一,那么它将编译,因为int之间存在隐式转换?和null(#1)以及int和int之间的关系?(# 2,# 3)。

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

#2


31  

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 10 is an int it then decides that the return type of this expression shall be an int as well. Since an int cannot be null (the third operand of the conditional operator) it complains.

基本情况是,条件操作符无法确定表达式的“返回类型”。由于编译器隐含地决定10是一个int,它然后决定这个表达式的返回类型也应该是int。由于int不能为null(条件操作符的第三个操作数),它会对此进行抱怨。

By casting the null to 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 10 to int? as well and had the same effect.

通过将null转换为Nullable ,我们可以明确地告诉编译器这个表达式的返回类型应该是Nullable 。你可以很容易地把10换成int?也有同样的效果。

#3


13  

Try this:

试试这个:

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

int ?结果=条件?10:默认(int ?);

#4


13  

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实现实际上以一种非常微妙和有趣的方式(对我来说)错误地进行了条件运算符的类型分析。我在这方面的文章是第一部分的类型推断问题。

#5


4  

Try one of these:

试试其中之一:

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

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

#6


4  

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.

问题是三元算子是根据你的第一个参数赋值来推断的。在这种情况下,它是一个int型,而不是可空int型。

You might have better luck with:

你可能会有更好的运气:

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

#7


3  

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的空实例。

#8


3  

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也不合适。

#9


3  

It's because the compiler determines the type of the conditional operator by it's 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.

这是因为编译器通过它的第二个和第三个操作数来确定条件运算符的类型,而不是通过你给结果赋值什么。在整数和空引用之间没有直接的转换,编译器可以使用空引用来确定类型。

#1


345  

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

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

GetBoolValue() ? 10 : null

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

10是一个int文字(不是int?) null是null。这两者之间没有隐含的转换,因此错误信息。

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 int and int? (#2, #3).

如果您将右边的表达式更改为下列表达式之一,那么它将编译,因为int之间存在隐式转换?和null(#1)以及int和int之间的关系?(# 2,# 3)。

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

#2


31  

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 10 is an int it then decides that the return type of this expression shall be an int as well. Since an int cannot be null (the third operand of the conditional operator) it complains.

基本情况是,条件操作符无法确定表达式的“返回类型”。由于编译器隐含地决定10是一个int,它然后决定这个表达式的返回类型也应该是int。由于int不能为null(条件操作符的第三个操作数),它会对此进行抱怨。

By casting the null to 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 10 to int? as well and had the same effect.

通过将null转换为Nullable ,我们可以明确地告诉编译器这个表达式的返回类型应该是Nullable 。你可以很容易地把10换成int?也有同样的效果。

#3


13  

Try this:

试试这个:

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

int ?结果=条件?10:默认(int ?);

#4


13  

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实现实际上以一种非常微妙和有趣的方式(对我来说)错误地进行了条件运算符的类型分析。我在这方面的文章是第一部分的类型推断问题。

#5


4  

Try one of these:

试试其中之一:

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

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

#6


4  

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.

问题是三元算子是根据你的第一个参数赋值来推断的。在这种情况下,它是一个int型,而不是可空int型。

You might have better luck with:

你可能会有更好的运气:

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

#7


3  

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的空实例。

#8


3  

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也不合适。

#9


3  

It's because the compiler determines the type of the conditional operator by it's 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.

这是因为编译器通过它的第二个和第三个操作数来确定条件运算符的类型,而不是通过你给结果赋值什么。在整数和空引用之间没有直接的转换,编译器可以使用空引用来确定类型。