使用条件运算符时没有隐式转换
本文关键字:转换 条件运算符 | 更新日期: 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。那里没有隐式转换(例如,因为一个转换不是从另一个派生的)。但是,您可以继续明确它并强制执行它(这是您在第二个和第三个工作示例中所做的),因为有可用的转换。