-2

I have a base class and two derived classes:

public class base1
{
    public int property1;
}
public class child1 : base1
{
    public int property2;
}
public class child2 : base1
{
    public int property3;
}

when I assign newProp variable like this:

int i = 2;
base1 newProp = (i == 0 ? new child1
{
   property1 = 1,
   property2 = 3
} : null);

it works fine and the newProp type changes to child1 class type, but what I try to do is something like this:

int i = 2;
base1 newProp = (i == 0 ? new child1
{
   property1 = 1,
   property2 = 3
} : new child2
{
   property1 = 4,
   property3 = 6
});

but I get this error

Type of conditional expression cannot be determined because there is no implicit conversion between `class1` and `class2`

is there any way to do this?

z.k
  • 45
  • 1
  • 8

2 Answers2

1

Just help the compiler by casting one of branches to the base class:

Base newProp = 
 (i == 0 
? (Base)new Child1 
{
    property1 = 1,
    property2 = 3
} 
: new Child2 
{
   property1 = 4,
   property3 = 6
});     
Wiktor Zychla
  • 47,367
  • 6
  • 74
  • 106
0

As mentioned in the comment by Lasse V. Karlsen, in C# 8.0 and earlier, the type of the first result operator and the second result operator must be the same or there must be an implicit conversion from one type to the other. (see ?: operator (C# reference))

Explicitly cast one of them to base1 should do the trick:

int i = 2;
base1 newProp = (i == 0
    ? (base1)new child1 
    {
       property1 = 1,
       property2 = 3
    }
    : new child2 
    {
       property1 = 4,
       property3 = 6
    });

or

int i = 2;
base1 newProp = (i == 0
    ? new child1 
    {
       property1 = 1,
       property2 = 3
    }
    : (base1)new child2 
    {
       property1 = 4,
       property3 = 6
    });

Beginning with C# 9.0, the result is target-typed. (again see ?: operator (C# reference))
But only if the target type is known (not using var).

In that case you won't get the error on your sample code.

abto
  • 1,583
  • 1
  • 12
  • 31
  • 1
    It's not always the type after the question mark. In C# 8 or earlier, the two branches a and b in `x ? a ? b` must either be the same type, or one of the types must be convertible to the other. In C# 9 it is OK if they're compatible with the target type of the whole expression, meaning in this case `Base` since the target type is `Base` due to the assignment. In C# 8 or earlier, the type of `(i == 2) ? "" : new object()` is `object`, not `string`, so it's not "the type of the element after the ?". – Lasse V. Karlsen Jul 25 '21 at 13:12