2011-01-23 18 views
6

L'esempio seguente mi sta dando questo errore:
[DCC Error] Unit2.pas(54): E2010 Incompatible types: 'IBar' and 'Unit2.TFoo<Unit2.IBar>'Problema con i generici e interfacce ed ereditarietà

Credo che il problema è da qualche parte intorno al Self.Create Perché dopo molti tentativi per farlo compilato ho accidentalmente entrato FFOO : = TBar (auto). Crea; e ha compilato e lavorato.

sto usando Delphi XE

IFoo = interface 
end; 

TFoo<T: IInterface> = class(TInterfacedObject, IFoo) 
private class var 
    FFoo: T; 
public class 
    function Instance: T; 
end; 

IBar = interface(IFoo) 
end; 

TBar = class(TFoo<IBar>, IBar) 
end; 

class function TFoo<T>.Instance: T; 
begin 
    if not Assigned(FFoo) then 
    begin 
    FFoo := Self.Create; 
    end; 
    Result := FFoo; 
end; 
+4

L'errore indica un numero di riga. Forse potresti indicare esattamente quale linea invece di indovinare dove potrebbe essere il problema? –

+1

L'errore è sulla linea dopo "fine". – RjK

+0

Il cast 'TBar (Self) .Create' non è voluto perché non sei sicuro che Self sia un TBar ** e ** romperà il concetto di generici (non utilizzabile per un'altra classe)! – TridenT

risposta

1

tuo TFoo non implementa T come interfaccia. Ecco perché FFoo e un'istanza di TFoo non sono compatibili. Se vuoi assegnare un'istanza di TFoo a FFoo devi hardcast.

+0

Intendi questo nella funzione Istanza: Risultato: = T (FFoo); Compila ma quando lo eseguo ottengo un AV sull'ultima parte della funzione. (Violazione di accesso all'indirizzo 00000001. Lettura di indirizzo 00000001.) – RjK

3

Il problema è in questa linea con la dichiarazione TBar:

FFoo := Self.Create; 

Per capire, spieghiamo i tipi dietro il codice [notare come questo]:

FFoo:[IBar] := Self:[TFoo(IBar)].Create():[TFoo<IBar>] 

Quindi, tu riassumere, abbiamo: [IBar] := [TFoo<IBar>]
Questi tipi sono compatibili?
Un [TFoo] implementa solo IFoo interfaccia, non IBar come si afferma nel codice

TFoo<T: IInterface> = class(TInterfacedObject, IFoo) 

Questo è l'errore di compilazione!
UPDATE: Soluzione 1
Per risolvere il problema: modificare la dichiarazione TBar

TBar = class(TFoo<IFoo>, IBar) 
end; 

UPDATE: Soluzione 2
Sostituire il FFoo := Self.Create da

FFoo := Self.Create.Instance; 

e così è lavori !

+0

Questa non è la soluzione perché il tipo di risultato della funzione Istanza sarà IFoo e non IBar. – RjK

+0

@RjK: ho aggiornato il mio post con ** Soluzione 2 **. Penso che questo sia quello che stavano cercando! – TridenT

+0

UPDATE: Soluzione 2 -> Ciò causerà un overflow dello stack. – RjK