问题
This question already has an answer here:
- Conditional operator assignment with Nullable<value> types? 5 answers
- Why doesn't this C# code compile? 4 answers
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?
回答1:
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.
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).
GetBoolValue() ? (int?)10 : null // #1
GetBoolValue() ? 10 : (int?)null // #2
GetBoolValue() ? 10 : default(int?) // #3
回答2:
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.
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.
回答3:
Try this:
int? result = condition ? 10 : default(int?);
回答4:
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.
回答5:
Try one of these:
int? x = GetBoolValue() ? (int?)10 : null;
int? x = GetBoolValue() ? 10 : (int?)null;
回答6:
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:
int? x = GetBoolValue() (int?)10 : null;
回答7:
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.
回答8:
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.
回答9:
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.
来源:https://stackoverflow.com/questions/858080/nullable-types-and-the-ternary-operator-why-is-10-null-forbidden