Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 604 Vote(s) - 3.49 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Type of conditional expression cannot be determined because there is no implicit conversion between 'int' and <null>

#1
Why does this not compile?

int? number = true ? 5 : null;

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

#2
`null` does not have any identifiable type - it just needs a little prodding to make it happy:

int? number = true ? 5 : (int?)null;
Reply

#3
The spec (§7.14) says that for conditional expression `b ? x : y`, there are three possibilities, either `x` and `y` both have a type *and* certain *good conditions* are met, only one of `x` and `y` has a type *and* certain *good conditions* are met, or a compile-time error occurs. Here, "certain good conditions" means certain conversions are possible, which we will get into the details of below.

Now, let's turn to the germane part of the spec:

> If only one of `x` and `y` has a type, and both `x` and `y` are implicitly convertible to that type, then that is the type of the conditional expression.

The issue here is that in

int? number = true ? 5 : null;

only one of the conditional results has a type. Here `x` is an `int` literal, and `y` is `null` which does *not* have a type **and `null` is not implicitly convertible to an `int`**<sup>1</sup>. Therefore, "certain good conditions" aren't met, and a compile-time error occurs.

There *are* two ways around this:

int? number = true ? (int?)5 : null;

Here we are still in the case where only one of `x` and `y` has a type. Note that `null` *still* does not have a type yet the compiler won't have any problem with this because `(int?)5` and `null` are both implicitly convertible to `int?` (§6.1.4 and §6.1.5).

The other way is obviously:

int? number = true ? 5 : (int?)null;

but now we have to read a *different* clause in the spec to understand why this is okay:

> If `x` has type `X` and `y` has type `Y` then
>
> - 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.
>
> - 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.

Here `x` is of type `int` and `y` is of type `int?`. There is no implicit conversion from `int?` to `int`, but there is an implicit conversion from `int` to `int?` so the type of the expression is `int?`.

<sup>1</sup>: Note further that the type of the left-hand side is ignored in determining the type of the conditional expression, a common source of confusion here.
Reply

#4
In `C# 9` this is now allowed [blog][1]



> <h1>Target typed ?? and ?</h1>
>
> Sometimes conditional ?? and ?: expressions don’t have an obvious shared type between the branches. Such cases fail today, but C# 9.0 will allow them if there’s a target type that both branches convert to:

Person person = student ?? customer; // Shared base type
int? result = b ? 0 : null; // nullable value type

Or your example:

// Allowed in C# 9.
int? number = true ? 5 : null;


[1]:

[To see links please register here]

-
Reply

#5
The 5 is an `int`, and `null` cannot be implicitly converted to `int`.

Here are ways to work around the issue:

int? num = true ? 5 : default(int?);
int? num = true ? 5 : new int?();

int? num = true ? 5 : null as int?;
int? num = true ? 5 : (int?)null;

int? num = true ? (int?)5 : null;
int? num = true ? 5 as int? : null;

int? num = true ? new int?(5) : null;

Also, anywhere you see `int?` you could use `Nullable<int>` instead.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through