Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ternary Operator syntax to choose implementation of Interface [duplicate]

I am wondering why this line of code doesn't compile:

ILogStuff Logger = (_logMode) ? new LogToDisc() : new LogToConsole();

Note that both classes LogToDiscand LogToConsole implement ILogStuff, and _logMode is a boolean variable. The error message I get is:

Error 3: Type of conditional expression cannot be determined because there is no implicit conversion between 'xxx.LogToDisc' and 'xxx.LogToConsole'

But why should there be one? What am I missing?

like image 527
EluciusFTW Avatar asked Apr 16 '14 09:04

EluciusFTW


2 Answers

There is not implicit conversion available for ternary operator. You need to cast the returned object by ternary operator to ILogStuff, This is very well explain in Eric Lippert's answer for the question Implicit conversion issue in a ternary condition

ILogStuff Logger = (_logMode) ? (ILogStuff) new LogToDisc() : (ILogStuff) new LogToConsole();

From chapter 7.13 of the C# Language Specification:

The second and third operands of the ?: operator control the type of the conditional expression. Let X and Y be the types of the second and third operands. Then,

  • If X and Y are the same type, then this is the type of the conditional expression.
  • Otherwise, 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.
  • Otherwise, 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.
like image 71
Adil Avatar answered Oct 13 '22 01:10

Adil


You need to cast to the interface:

ILogStuff Logger = (_logMode) ? (ILogStuff)new LogToDisc() : new LogToConsole();

The specification describes the behaviour of the conditional operator:

7.14 Conditional operator

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

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.

There is no implicit conversion between LogToDisc and LogToConsole in either direction, so the compilation fails. If you fix one of the types to ILogStuff the implicit conversion from the other type will exist.

like image 39
Lee Avatar answered Oct 13 '22 00:10

Lee