2014-11-04 6 views
7

Ricevo un'eccezione run-time quando provo a trasmettere un oggetto a un'interfaccia che sono abbastanza sicuro che implementa.Riferimenti all'interfaccia downcasting

Ho le seguenti interfacce:

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

ho le seguenti classi:

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

Poi, ho provare quanto segue:

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

Questo genera un'eccezione a run -time:

Piattaforma :: InvalidCastException^nella posizione di memoria 0x04AFD83C. HRESULT: 0x80004002 Nessuna interfaccia supportata

Per quanto posso dire, questo dovrebbe funzionare. C'è qualcosa di sbagliato in ciò che sto cercando di fare, o i sintomi indicano un problema di implementazione (qualcosa è diverso da quanto affermato in precedenza)?

+1

Puoi mostrare 'getSequence'? Ho provato a riprodurre il tuo codice e non ottengo un'eccezione. Per me funziona. Tutto ciò che ho cambiato è stata la riga che chiama 'getSequence' a questo:' ISMILTimeContainer^container = ref new Sequence(); 'Forse' getSequence' non restituisce una 'Sequence'? –

+0

Non esiste una cosa come ereditare una classe in WinRT. È fatto internamente usando la composizione. Penso che in questo caso potresti usare safe_cast, che dovrebbe funzionare "across" e non solo su e giù. Pensalo come un cast pathway, credo. –

risposta

3

Il container è un ISMILTimeContainer creato dal cast implicito. Si tratta di upcasting, che trasmette un oggetto di classe derivata (il valore restituito di getSequence(), un Sequence) a un oggetto principale o di classe base (ISMILTimeContainer).

Quando si tenta di eseguire il downcast su un ISMILSequence nella successiva istruzione, poiché si dispone di una catena di ereditarietà, si passano i controlli del compilatore utilizzando static_cast<ISMILSequence^>.

Tuttavia, C++/CX gestisce anche controlli runtime [1], e in questo caso sembra che la variabile container, di tipo ISMILTimeContainer, non ha tutte le informazioni necessarie per formare un ISMILSequence nella seconda dichiarazione. Sebbene sia un ISMILSequence IS-A ISMILTimeContainer, l'opposto non è vero.

Per informazioni su up-casting e down-casting, vedere [2] o altri risultati di Google. Le sezioni successive in questo post del blog potrebbero essere di aiuto.