13
double? test = true ? null : 1.0;

In my book, this is the same as

if (true) {
  test = null;
} else {
  test = 1.0;
}

But the first line gives this compiler error:

Type of conditional expression cannot be determined because there is no implicit conversion between '<null>' and 'double'.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
Robbert Dam
  • 4,027
  • 10
  • 39
  • 58
  • you can always submit the Errata to the book publisher :) or maybe it's already been found and it's in the book Errata (normally in the publisher website) – balexandre May 06 '09 at 10:21
  • 3
    The expression "in my book" means "as far as I know" - it's not a reference to an actual book :-) – Mark Pattison May 06 '09 at 10:25
  • 1
    Your position that one is the same as the other is not borne out by either the language specification or the implementation; those two things are very different indeed! The error message is correct; the language specification requires that the expression be implicitly convertible to double?, which requires in turn that the expression have a known type. The expression does not have a known type, hence the error. – Eric Lippert May 06 '09 at 21:30
  • possible duplicate of [Conditional operator assignment with Nullable types?](http://stackoverflow.com/questions/75746/conditional-operator-assignment-with-nullablevalue-types) – nawfal Apr 20 '13 at 00:49
  • possible duplicate of [Nullable types and the ternary operator: why is \`? 10 : null\` forbidden?](http://stackoverflow.com/questions/858080/nullable-types-and-the-ternary-operator-why-is-10-null-forbidden) – Peter O. Apr 20 '13 at 01:24
  • To me, the question is asking: Why doesn't the compiler see that both expressions are implicitly convertible to type `double?`, and automatically use this as the type of the conditional expression? If the answer is "because the language spec doesn't allow this", why hasn't MS (or ECMA or ISO or whoever) amended the language spec so that it does? – Stewart Aug 23 '19 at 15:14

4 Answers4

28

This happens because the compiler tries to evaluate the statement from right to left. This means that it sees 1.0 and it decides it is double (not double?) and then it sees null.

So there is clearly no implicit conversion between double and null (in fact there is no implicit conversion between Struct and null).

What you can do is explicitly tell the compiler that one of the two expressions that are convertible to each other.

double? test = true ? null : (double?) 1.0;    // 1
double? test = true ? (double?)null : 1.0;     // 2
double? test = true ?  default(double?) : 1.0; // 3
double? test = true ? new double?() : 1.0;     // 4
kuskmen
  • 3,648
  • 4
  • 27
  • 54
leppie
  • 115,091
  • 17
  • 196
  • 297
8
double? test = true ? (double?)null : 1.0;

will work. That's because there is no conversion from the type of the first expression (null) to the type of the second expression (double).

David Schmitt
  • 58,259
  • 26
  • 121
  • 165
4

The left hand side of the assignment is not used when deducing the type of an ?: expression.

In b ? A : B, the types of A and B must either be the same, or one must be implicitly convertible to the other.

James Hopkin
  • 13,797
  • 1
  • 42
  • 71
  • 2
    There is some subtlety here -- is it that the type of A must be convertible to the type of B, or that A must be convertible to the type of B? The compiler actually gets it wrong! See this post http://blogs.msdn.com/ericlippert/archive/2006/05/24/type-inference-woes-part-one.aspx for details. – Eric Lippert May 06 '09 at 21:24
2

Because the compiler can't figure out that for null and 1.0 to be compatible, the values need to be cast to double?. This needs to be explicitly stated.

double? test = true ? (double?) null : 1.0;
J. Steen
  • 15,470
  • 15
  • 56
  • 63
  • `null` (the literal) **is** convertible to `double?`. Otherwise the accepted answer with `true ? null : (double?)1.0` could not work. What `null` is not convertible to is `double`. – Jeppe Stig Nielsen Mar 22 '15 at 11:41
  • @JeppeStigNielsen Implicitly. I totally agree it's convertible. – J. Steen Mar 22 '15 at 16:33