2011-01-23 16 views
6

Poniższy przykład daje mi ten błąd:
[DCC Error] Unit2.pas(54): E2010 Incompatible types: 'IBar' and 'Unit2.TFoo<Unit2.IBar>'problem z rodzajowych i interfejsów i dziedziczenia

Myślę, że problem jest gdzieś wokół Self.Create Ponieważ po wielu próbach, aby to zestawionych przypadkowo wszedł FFoo : = TBar (Self). Utwórz; i skompilował i pracował.

używam 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

Błąd informuje o numerze linii. Być może możesz wskazać dokładnie, co to jest linia zamiast zgadywać, gdzie może być problem? –

+1

Błąd pojawia się po "zakończeniu". – RjK

+0

Oddanie 'TBar (Self) .Create' jest niepożądane, ponieważ nie masz pewności, że Self jest TBar ** i ** złamie pojęcie generycznych (nie nadaje się do użycia dla innej klasy)! – TridenT

Odpowiedz

1

Twój Tfoo nie implementuje T jako interfejs. Właśnie dlatego FFoo i instancja TFoo nie są kompatybilne. Jeśli chcesz przypisać instancję TFoo do FFoo, musisz ją przeskanować.

+0

Czy masz na myśli to w funkcji Instancja: Wynik: = T (FFoo); Kompiluje się, ale kiedy go uruchomię, dostaję AV na ostatnim końcu funkcji. (Naruszenie dostępu pod adresem 00000001. Odczyt adresu 00000001.) – RjK

3

Problem jest w tym zgodnie z deklaracją TBar:

FFoo := Self.Create; 

Aby zrozumieć, wyjaśnijmy typy za kodem z [zauważyć, jak to]:

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

Więc tu podsumować, mamy: [IBar] := [TFoo<IBar>]
Czy te typy są kompatybilne?
[Tfoo] tylko realizuje IFoo interfejs, nie IBAR jak stwierdzono w kodzie

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

Jest to błąd kompilacji!
AKTUALIZACJA: Rozwiązanie 1
Aby rozwiązać ten problem: zmienić deklarację TBar

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

AKTUALIZACJA: Rozwiązanie 2
Wymień FFoo := Self.Create przez

FFoo := Self.Create.Instance; 

a więc Prace !

+0

To nie jest rozwiązanie, ponieważ typem wyniku funkcji Instancja będzie IFoo, a nie IBar. – RjK

+0

@RjK: Zaktualizowałem swój wpis ** Rozwiązanie 2 **. Myślę, że to właśnie szukali! – TridenT

+0

AKTUALIZACJA: Rozwiązanie 2 -> Spowoduje to przepełnienie stosu. – RjK