两个对象之间没有隐式转换?——操作符

本文关键字:转换 操作符 两个 之间 对象 | 更新日期: 2023-09-27 18:08:50

我刚刚得到以下错误:

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

尝试实现以下代码行时发生错误:

ViewModel myViewModel = conditionIsTrue() ? _viewModelA : _viewModelB;

这两个ViewModels都继承自ViewModel,但它们是两个不同的子类。

但是,如果我避免使用?操作符和使用 if/else 而不是工作原理:
ViewModel myViewModel;
if (conditionIsTrue(){
   myViewModel = _viewModelA;
}else{
   myViewModel = _viewModelB;
}

你能告诉我为什么会这样吗?

两个对象之间没有隐式转换?——操作符

即使它们共享公共基,您仍然需要显式地强制转换它们。

ViewModel myViewModel = conditionIsTrue() 
    ? (ViewModel)_viewModelA 
    : (ViewModel)_viewModelB;
查看c#文档:

?:操作符的第二个和第三个操作数控制条件表达式的类型。设X和Y分别为第二个和第三个操作数的类型。然后,

如果X和Y是相同的类型,那么这就是条件表达式的类型。

否则,如果存在从X到Y的隐式转换(第6.1节),但不存在从Y到X的隐式转换,则Y是条件表达式的类型。

否则,如果存在从Y到X的隐式转换(第6.1节),但不存在从X到Y的隐式转换,则X是条件表达式的类型。

否则,无法确定表达式类型,并发生编译时错误。

表达式

conditionIsTrue() ? _viewModelA : _viewModelB
在真正考虑ViewModel myViewModel =部分之前,对

单独进行评估。此操作符的结果必须求值为单一类型。在上述表达式的上下文中,编译器不清楚该使用哪种类型,因此会抛出错误。我建议将其中一个转换为ViewModel,以便编译器知道表达式的类型是什么:

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

或者像你的第二个例子那样在单独的行中做:

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

这个问题在这里已经有了答案,我引用c#规范:

?:操作符的第二个和第三个操作数控制条件表达式的类型。设X和Y分别为第二个和第三个操作数的类型。然后,

如果X和Y是相同的类型,那么这就是条件表达式的类型。

否则,如果存在从X到Y的隐式转换(第6.1节),但不存在从Y到X的隐式转换,则Y是条件表达式的类型。

否则,如果存在从Y到X的隐式转换(第6.1节),但不存在从X到Y的隐式转换,则X是条件表达式的类型。

否则,无法确定表达式类型,并发生编译时错误

你的问题是实际上不存在隐式转换。正如 havard S已经说过的:必须显式地将两者中的一个强制转换为基类,才能进行隐式转换。