我有这些类,相关位的部分列表。
public class IVRTopology {}
public abstract class SANSwitch
{ public string name { get; set; }
}
public class CiscoSwitch : SANSwitch
{
public IVRTopology IVRTop = new IVRToplogy()
}
class SwitchViewModel : INotifyPropertyChanged
{
public SANSwitch sanswitch { get; set; }
}
当我做这样的事情时:
SwitchViewModel svm = new SwitchViewModel();
svm.sanswitch = new CiscoSwitch();
IVRTopology topo = svm.sanswitch.IVRTop;
编译器警告我svm.sanswitch属于SANSwitch类型,如果我试图访问IVRTop,它就没有IVRTop的定义:
IVRTopology topo = (CiscoSwitch)svm.SANSwitch.IVRTop
也不起作用。我不想将IVRTopology的定义添加到抽象类中,因为我将有其他子类不能使用它。演员阵容有问题吗?我怎样才能做到这一点?我希望视图模型最终支持不同类型的开关。
答案 0 :(得分:4)
Casting是一个比.
运算符更低的优先级操作。
因此,当您运行以下代码时:
IVRTopology topo = (CiscoSwitch)svm.SANSwitch.IVRTop
您正在有效地运行
var ivrTop = svm.SANSwitch.IVRTop;
IVRTopology topo = (CiscoSwitch)ivrTop;
简单的解决方法是使用括号强制执行正确的分辨率:
IVRTopology topo = ((CiscoSwitch)svm.SANSwitch).IVRTop
答案 1 :(得分:1)
当您真正想要首先投射svm.SANSwitch.IVRTop
时,您正在投射svm.SANSWitch
的结果:
((CiscoSwitch) svm.SANSwitch).IVRTop
更好的是,在C#中你有安全的转换(因为(CiscoSwitch) svm.SANSwitch
如果它的类型不正确可能会引发错误),你可以做这样的事情:
(svm.SANSwitch as CiscoSwitch)?.IVRTop
首先我们对CiscoSwitch
进行安全转换,可能为null,然后我们Null Propagate ?
并检索该值。 Null Propagation仅在结果值不为空时才有效 - 所以在这一行中一切都非常安全。然后你可能想要检查它是否在第一时间成功。
答案 2 :(得分:0)
你的语法错了。
IVRTopology topo = ((CiscoSwitch)svm.SANSwitch).IVRTop;