使用条件运算符时没有隐式转换

本文关键字:转换 条件运算符 | 更新日期: 2023-09-27 17:57:54

我有以下类:

abstract class AClass { }
class Foo : AClass { }
class Bar : AClass { }

当我尝试使用它们时:

AClass myInstance;
myInstance = true ? new Foo() : new Bar();

此代码将不会编译,因为

但以下样本编译正常:

if (true)
{
    myInstance = new Foo();
}
else
{
    myInstance = new Bar();
}

这也可以:

myInstance = true ? (AClass) new Foo() : new Bar();

myInstance = true ? new Foo() : (AClass) new Bar();

为什么条件运算符和if子句的行为有这么大的区别?

使用条件运算符时没有隐式转换

这是预期的行为。

由于X和Y之间不存在隐式转换(即使它们共享一个公共基,它们之间也不存在隐式转换),因此需要显式将其中一个强制转换为基类,以便存在隐式转化。

C#规范的详细解释:

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

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

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

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

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

三元运算符与if子句没有太大区别,只是语句中的区别。

在您的第一个工作示例中,您在Foo和AClass或Bar和AClass之间进行转换,这显然很好。

在第二个工作示例中,您告诉三元运算符查看AClass和Bar。在第三个工作示例中,您告诉三元运算符查看Foo和AClass。这些显然有明显的转变。

在非工作示例中,您告诉它查看Foo和Bar。那里没有隐式转换(例如,因为一个转换不是从另一个派生的)。但是,您可以继续明确它并强制执行它(这是您在第二个和第三个工作示例中所做的),因为可用的转换。