0

I just got the following error:

There is no implicit conversion between 'ViewModelA' and 'ViewModelB'.

This error occured while trying to implement the following line of code:

ViewModel myViewModel = conditionIsTrue() ? _viewModelA : _viewModelB;

Both of the ViewModels inherits from ViewModel but are two different subclasses.

However, if I avoid the ?-operator and use if/else instead it works:

ViewModel myViewModel;
if (conditionIsTrue(){
   myViewModel = _viewModelA;
}else{
   myViewModel = _viewModelB;
}

Could you tell me why this happens?

Frame91
  • 3,670
  • 8
  • 45
  • 89

3 Answers3

2

The expression

conditionIsTrue() ? _viewModelA : _viewModelB

is evaluated on its own before the ViewModel myViewModel = part is really considered. The result of this operator must evaluate to a single type. In the context of the above expression, it's not obvious to the compiler what type to use, so it throws an error. I'd suggest casting one of them to ViewModel so that the compiler knows what the expression's type is:

ViewModel myViewModel = conditionIsTrue() ? (ViewModel)_viewModelA : _viewModelB;
//or with var
var myViewModel = conditionIsTrue() ? (ViewModel)_viewModelA : _viewModelB;

Or maybe just doing it on separate lines like your second example:

ViewModel myViewModel;
if (conditionIsTrue() {
   myViewModel = _viewModelA;
} else {
   myViewModel = _viewModelB;
}
Tim S.
  • 55,448
  • 7
  • 96
  • 122
2

Even if they share common base, you still need to explicitly cast them.

ViewModel myViewModel = conditionIsTrue() 
    ? (ViewModel)_viewModelA 
    : (ViewModel)_viewModelB;

Check c# documentation:

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 (Section 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 (Section 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.

avidenic
  • 653
  • 7
  • 17
1

This question has been aswered here and I quote the C# 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 (Section 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 (Section 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

Your problem is that no implicit conversion actually exists. As Håvard S already said: You have to explicitly cast one of the two to the the base class for implicit conversion to occur.

Community
  • 1
  • 1
ThreeFx
  • 7,250
  • 1
  • 27
  • 51
  • Thanks! That does make sense now ;) – Frame91 Jun 14 '14 at 22:31
  • I've been reading up on this, as I find it ridiculous to add explicit casts to object when the expected result is an object. Now I think the spec itself is flawed. Didn't anyone involved look at the actual use cases? – Thomas Eyde Dec 25 '14 at 13:23