向下转换接口参考

Posted

技术标签:

【中文标题】向下转换接口参考【英文标题】:Downcasting interface references 【发布时间】:2014-12-31 18:22:48 【问题描述】:

当我尝试将对象强制转换为我很确定它实现的接口时,我遇到了运行时异常。

我有以下接口:

public interface class ISMILTimeContainer;
public interface class ISMILSequence : ISMILTimeContainer;
public interface class ISMILParallel : ISMILTimeContainer;

我有以下课程:

ref class TimeContainer : public ISMILTimeContainer;
ref class Sequence : public TimeContainer, ISMILSequence;
ref class Parallel : public TimeContainer, ISMILParallel;

然后,我尝试以下操作:

ISMILTimeContainer^ container = getSequence(); // returns a Sequence^
ISMILSequence^ sequence = static_cast<ISMILSequence^>(container);

这会在运行时引发异常:

Platform::InvalidCastException ^ 在内存位置 0x04AFD83C。 HRESULT:0x80004002 不支持这样的接口

据我所知,这应该有效。我正在尝试做的事情是否有问题,或者症状是否表明实施问题(与上面声称的不同)?

【问题讨论】:

你能显示getSequence吗?我试图重现您的代码并且没有出现异常。对我来说它有效。我所做的只是将getSequence 调用为:ISMILTimeContainer^ container = ref new Sequence(); 也许getSequence 不会返回Sequence 在 WinRT 中没有继承类这样的事情。它是在内部使用组合完成的。我认为在这种情况下你可以使用 safe_cast,它应该“跨越”工作,而不仅仅是上下。我猜它是一个寻路演员。 【参考方案1】:

您的container 是由隐式转换创建的ISMILTimeContainer。这是向上转换,将派生类对象(getSequence() 的返回值,Sequence)转换为父类或基类对象(ISMILTimeContainer)。

当您尝试在下一条语句中向下转换为 ISMILSequence 时,因为您有一个继承链,所以您使用 static_cast&lt;ISMILSequence^&gt; 通过编译器检查。

但是,C++/CX 也运行运行时检查 [1],在这种情况下,您的 container 变量(类型为 ISMILTimeContainer)似乎没有形成 ISMILSequence 所需的所有信息你的第二个陈述。虽然是ISMILSequence IS-A ISMILTimeContainer,但反之则不然。

有关向上转换和向下转换的信息,请参阅[2] 或其他谷歌搜索结果。本博文后面的部分可能会有所帮助。

【讨论】:

以上是关于向下转换接口参考的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript 接口向下转换

使用接口包装库而不需要向下转换

模拟对象的方法在接口向下转换后返回null

Java多态&接口&转型

Java多态&接口&转型

使gridview数据源留在界面中而不是向下转换为对象