You need to cast at least one of the operands to IClientSubscription
:
Subscription = (IsLive)
? (IClientSubscription)new LiveSubscription()
: new DisconnectedSubscription();
The reason is that the ternary expression is of a certain type which is determined by the operands. Basically, it tries to cast the second operand to the type of the first or vice versa. Both fail here, because LiveSubscription
isn't an DisconnectedSubscription
and vice versa.
The compiler doesn't check whether both share a common base type.
Trying to answer your question in the comment:
No, ternary expressions are not some sort of object, but a ternary expression is the right hand part of an assignment. Each right hand part expression of an assignment has a certain type, otherwise it would be impossible to assign this expression to the variable on the left hand side.
Examples:
var x = Guid.NewGuid()
The right hand side expression (Guid.NewGuid()
) is of type Guid
, because the method NewGuid()
returns a Guid
.
var x = y.SomeMethod()
The right hand side expression is of the type of the return type of SomeMethod()
.
var x = IsLive ? "a" : 1
This is obviously invalid, isn't it? What type should x
be? A string
or an int
?
This would lead to the exact same error message that you had with your code.
Your example a bit changed:
var subscription = (IsLive) ? new LiveSubscription()
: new DisconnectedSubscription();
Note the var
before subscription
, we now initialize a new variable, not an existing. I think even here, it is obvious what the problem is: What type should subscription
be? LiveSubscription
or DisconnectedSubscription
? It can be neither, because depending on IsLive
it needs to be either the one or the other.
About the comparison with if
:
In your code where you assign a new LiveSubscription
instance or a new DisconnectedSubscription
instance to Subscription
an implicit cast to IClientSubscription
is occurring, because the compiler knows that Subscription
is of type IClientSubscription
and both LiveSubscription
and DisconnectedSubscription
can implicitly be converted to that interface.
The assignment with the ternary expression is a bit different, because the compiler first tries to evaluate the ternary expression and only afterwards it tries to assign it to Subscription
. This means that the compiler doesn't know that the result of the ternary expression needs to be of type IClientSubscription
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…