Why does null need an explicit type cast here?<>
This question already has an answer here:
- Nullable types and the ternary operator: why is `? 10 : null` forbidden? [duplicate] 9 answers
- Conditional operator cannot cast implicitly? 3 answers
From chapter 7.13 of the C# Language Specification:
The second and third operands of the ?: operator control the type of the conditional expression. Let X and Y be the types of the second and third operands. Then,
- If X and Y are the same type, then this is the type of the conditional expression.
- Otherwise, if an implicit conversion (§6.1) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression.
- Otherwise, if an implicit conversion (§6.1) exists from Y to X, but not from X to Y, then X is the type of the conditional expression.
- Otherwise, no expression type can be determined, and a compile-time error occurs.
In your case, there is no implicit conversion from int to null nor the other way around. Your cast solves the problem, int is convertible to int?
The both alternatives of ?: operator must be of the same type. Otherwise, the compiler cannot deduce the type of the whole conditional expression.
null is not an int, so you need to give a hint to the compiler that the resulting type is int?.
Edit: as the others pointed out, the two types don't need to be the same, but one of them should be castable to another (that another one will be the result type). See specs for more details.
You can save yourself from casting if you use default(int?) instead of null.
int a = 42; int? b = (a != 0 ? a : default(int?));
it's because when you use that kind of notation, both member must be of the same type, so you have to explicitly say "this member is a int?".
is it clear ?
When you use the conditional operator with operands of different types, the compiler will check whether one of the types can be implicitly converted to the other type.
If neither type can be implicitly converted to the other one, it will give an error, even if there is a third type that they can both implicitly convert to. The compiler will not insert an implicit conversion on both sides at once.
In your case, both int and null requires implicit conversions to become int?, so it doesn't work. You need to change your code so that one side is an int? and the other side can be implicitly converted to int?. The simplested way to do this is to replace null with new int?(), like this:
int? b = (a != 0 ? a : new int?());
This only requires one implicit conversion (int to int?).
This is pretty much a duplicate of one of my questions, regarding the conditional operator. It's not the null, it really is the :.
The answer accepted there is pretty good, from none other than Eric Lippert, who is on the C# compiler team.