我有以下课程:
abstract class AClass { }
class Foo : AClass { }
class Bar : AClass { }
Run Code Online (Sandbox Code Playgroud)
当我试图使用它们时:
AClass myInstance;
myInstance = true ? new Foo() : new Bar();
Run Code Online (Sandbox Code Playgroud)
此代码将无法编译,因为"无法确定条件表达式的类型,因为'CSharpTest.Class1.Foo'和'CSharpTest.Class1.Bar'之间没有隐式转换"
但是以下样本编译好了:
if (true)
{
myInstance = new Foo();
}
else
{
myInstance = new Bar();
}
Run Code Online (Sandbox Code Playgroud)
这也没问题:
myInstance = true ? (AClass) new Foo() : new Bar();
Run Code Online (Sandbox Code Playgroud)
要么
myInstance = true ? new Foo() : (AClass) new Bar();
Run Code Online (Sandbox Code Playgroud)
为什么条件运算符和if子句的行为有如此大的差异?
Håv*_*d S 16
这是预期的行为.
由于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。那里没有隐式转换(例如,因为一个转换不是从另一个派生的)。但是您可以继续明确它并进行转换(这就是您在第二个和第三个工作示例中所做的事情),因为有可用的转换。
| 归档时间: |
|
| 查看次数: |
4232 次 |
| 最近记录: |