Ternary operator and covariant coercion

I declare a variable

IList<int> list;

      

then I write a statement,

if(true)
{
    list = new List<int>();
}
else
{
    list = new int[0];
}

      

I have trivial and pointless code that compiles without warning. If I write an expression,

list = true ? new List<int>() : new int[0];

      

I am getting a compiler warning,

There is no implicit conversion between 'System.Collections.Generic.List <int>' and 'int []'

Why does the ternary operator have this limitation? Both List<int>

and int[]

implement IList<int>

.


Send reply

From section 7.14 Conditional Operator of C # 5.0 BOM

The second and third operands, x and y, of the ?: operator control the type of the conditional expression.

  • If x is of type X and y is of type Y, then

    • If the implicit conversion (ยง6.1) exists from X to Y but not Y to X, then Y is the type of the conditional expression.

    • If the 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, the type of the expression cannot be determined and a compile-time error occurs.

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

  • Otherwise, the type of the expression cannot be determined and a compile-time error occurs.

+3


source to share


2 answers


This is not an assignment problem list

. This is an expression problem true ? new List<int>() : new int[0]

. This expression is not legal under any circumstances.

If you link to the documentation , you will find this information.



Any type of expression first_expression and second_expression must be the same, or an implicit conversion must exist from one type to another.

In this case, this is not the case.

+6


source


Both List<int>

and int[]

implement many things ( IEnumerable<int>

, IReadOnlyCollection<int>

etc.). It's hard for the compiler to know what you mean without giving it a hint:

list = true ? (IList<int>) new List<int>() : new int[0];

      



Remember that expressions are evaluated internally. This way your ternary operator is evaluated before the compiler looking at what you are trying to assign it to. So there must be some implicit conversion available from the type on one side to the type on the other.

In the if / else example, you are actually performing List<int>

in IList<int>

as your own operation without trying to concatenate it with first int[]

.

+2


source







All Articles