以下代码给出了 Main 函数第二行标题中的错误。
public class P {}
public class B : P {}
public class A : P {}
void Main()
{
P p = GetA()??GetB();
}
public A GetA()
{
return new A();
}
public B GetB()
{
return new B();
}
像这样对线路进行简单的调整
p = (P)GetA()??GetB();
or
p = GetA()??(P)GetB();
works.
我很好奇为什么编译器不明白两者都是左侧容器的子类并且允许在没有强制转换的情况下进行操作?
左侧参数的类型必须与右侧的类型兼容,反之亦然。换句话说,必须存在从B
to A
或来自A
to B
.
var a = x ?? y;
在上面,如果有一个隐式转换y
to x
那么类型x
成为表达式的类型。如果没有隐式转换y
to x
,但是有一个隐式转换x
to y
,那么类型y
成为表达式的类型。如果两个方向都不存在转换,则繁荣;编译错误。从规格来看:
表达式 a ?? 的类型b 取决于操作数类型之间可以使用哪些隐式转换。按照优先顺序, ?? 的类型b 是 A0、A 或 B,其中 A 是 a 的类型,B 是 b 的类型(前提是 b 具有类型),如果 A 是可空类型,则 A0 是 A 的基础类型,否则是 A 。具体来说,一个?? b 的处理如下:
• 如果A 不是可为空类型或引用类型,则会发生编译时错误。
• 如果A 是可为空类型并且存在从b 到A0 的隐式转换,则结果类型为A0。在运行时,首先评估 a。如果 a 不为 null,则将 a 解包为类型 A0,这将成为结果。否则,对 b 进行求值并转换为 A0 类型,这就是结果。
• 否则,如果存在从b 到A 的隐式转换,则结果类型为A。在运行时,首先计算a。如果 a 不为 null,则 a 成为结果。否则,对 b 进行求值并将其转换为类型 A,这就是结果。
• 否则,如果b 具有类型B 并且存在从A0 到B 的隐式转换,则结果类型为B。在运行时,首先对a 求值。如果 a 不为 null,则将 a 解包为类型 A0(除非 A 和 A0 是同一类型)并转换为类型 B,这将成为结果。否则,对 b 进行求值并成为结果。
• 否则,a 和b 不兼容,并且会发生编译时错误。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)