2011-12-11 11 views
18

Qual è il motivo per cui questo non verrà compilato?Quando una classe implementa un'interfaccia discendente, perché non conta automaticamente come l'implementazione dell'interfaccia di base?

type 
    IInterfaceA = interface ['{44F93616-0161-4912-9D63-3E8AA140CA0D}'] 
    procedure DoA; 
    end; 

    IInterfaceB = interface(IInterfaceA) ['{80CB6D35-E12F-462A-AAA9-E7C0F6FE0982}'] 
    procedure DoB; 
    end; 

    TImplementsAB = class(TSingletonImplementation, IInterfaceB) 
    procedure DoA; 
    procedure DoB; 
    end; 

var 
    ImplementsAB: TImplementsAB; 
    InterfaceA: IInterfaceA; 
    InterfaceB: IInterfaceB; 
begin 
    ImplementsAB := TImplementsAB.Create; 
    InterfaceA := ImplementsAB; >> incompatible types 
    ... 
end 

In contrasto con questo è come faccio funzionare:

InterfaceA := ImplementsAB as InterfaceB; 

o

InterfaceA := InterfaceB; 

Voglio dire, se IInterfaceB eredita da IInterfaceA e TImplementsAB implementa IInterfaceB, non sarebbe logico per implementare anche IInterfaceA ed essere compatibile di tipo?

risposta

27

Questo perché all'inizio OLE/COM aveva un bug e Borland ha deciso di essere compatibile con esso. Questo è menzionato in questo articolo: New Delphi language feature: Multiple inheritance for interfaces in Delphi for .NET. La soluzione è elencare esplicitamente tutte le interfacce degli antenati nella classe come ha scritto Mikael.

Alcune citazioni dal articolo collegato:

il problema era in COM sé. Per caricare un modulo, COM caricava la DLL, GetProcAddress su un punto di ingresso noto che doveva essere esportato dalla DLL, chiamare la funzione DLL per ottenere un'interfaccia IUnknown e quindi QueryInterface per IClassFactory. Il problema è stato quando Microsoft ha aggiunto il supporto per IClassFactory2, hanno aggiunto QueryInterface per IClassFactory2 dopo il codice esistente che ha interrogato per IClassFactory. IClassFactory2 sarebbe richiesto solo se la query per IClassFactory non è riuscita.

Pertanto, COM non richiederebbe mai IClassFactory2 su alcun server COM che abbia implementato sia IClassFactory2 che IClassFactory.

Questo errore è presente in COM da molto tempo. Microsoft ha dichiarato che non è stato possibile correggere il caricatore COM con un service pack del sistema operativo perché Word ed Excel (al momento) si basavano sul comportamento del buggy. Indipendentemente dal fatto che sia stato corretto nelle ultime versioni di COM o meno, Borland deve fornire un modo per preservare questo comportamento in Delphi Win32 per il prossimo futuro. L'aggiunta improvvisa di tutti gli antenati a una classe di implementazione che prima non esisteva è molto probabile che interrompa il codice esistente che involontariamente rientra nello stesso modello del caricatore COM.

+6

+1 Non sapevo il motivo, grazie! –

+1

+1 anche da parte mia. –

+0

Quale primo "bug" OLE/COM? –

6

Un altro modo per farlo funzionare è includere entrambe le interfacce nella dichiarazione di classe.

TImplementsAB = class(TSingletonImplementation, IInterfaceA, IInterfaceB) 
    procedure DoA; 
    procedure DoB; 
end; 

Credo che questo è ciò che è necessario per il compilatore per rendersi conto che TImplementsAB implementa sia IInterfaceA e IInterfaceB.

Problemi correlati