2010-08-26 8 views
7

se dan a continuación el código, la cual es una versión muy reducida de la código real, me sale el siguiente error:método genérico de regresar interfaz genérica en Delphi 2010

[DCC error] Unit3.pas (31): E2010 tipos incompatibles: 'IXList < Unit3.TXList <T> .FindAll.S >' y 'TXList < Unit3.TXList <T> .FindAll.S >'

En la función FindAll <S>.

Realmente no puedo ver por qué ya que no hay ningún problema con la función anterior muy similar.

¿Alguien puede arrojar algo de luz sobre él?
¿Soy yo o es un error en el compilador?

unidad Unit3;

interface 
uses Generics.Collections; 

type 
    IXList<T> = interface 
    end; 

    TXList<T: class> = class(TList<T>, IXList<T>) 
    protected 
    FRefCount: Integer; 
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; 
    function _AddRef: Integer; stdcall; 
    function _Release: Integer; stdcall; 
    public 
    function Find: IXList<T>; 
    function FindAll<S>: IXList<S>; 
    end; 

implementation 
uses Windows; 

function TXList<T>.Find: IXList<T>; 
begin 
    Result := TXList<T>.Create; 
end; 

function TXList<T>.FindAll<S>: IXList<S>; 
begin 
    Result := TXList<S>.Create; // Error here 
end; 

function TXList<T>.QueryInterface(const IID: TGUID; out Obj): HResult; 
begin 
    Result := E_NoInterface; 
end; 

function TXList<T>._AddRef: Integer; 
begin 
    InterlockedIncrement(FRefCount); 
end; 

function TXList<T>._Release: Integer; 
begin 
    InterlockedDecrement(FRefCount); 
    if FRefCount = 0 then Self.Destroy; 
end; 

end. 

¡Gracias por las respuestas! Parece un error de compilación con una solución aceptable disponible.

Con la interfaz declarado como

IXList<T: class> = interface 
    function GetEnumerator: TList<T>.TEnumerator; 
end; 

y FindAll implementan como

function TXList<T>.FindAll<S>: IXList<S>; 
var 
    lst: TXList<S>; 
    i: T; 
begin 
    lst := TXList<S>.Create; 
    for i in Self do 
    if i.InheritsFrom(S) then lst.Add(S(TObject(i))); 

    Result := IXList<S>(IUnknown(lst)); 
end; 

lo tengo trabajando en un ejemplo sencillo.

Hacer algo como:

var 
    l: TXList<TAClass>; 
    i: TASubclassOfTAClass; 
begin 
. 
. 
. 
for i in l.FindAll<TASubclassOfTAClass> do 
begin 
    // Do something with i 
end; 

Respuesta

5

Con tres pequeñas modificaciones (Interfaz II, FindAll con "S: clase" [Gracias Mason] y las tipografías en FindAll) lo obtuve compilando.

código completo:

unit Unit16; 

interface 

uses 
    Generics.Collections; 

type 
    IXList<T> = interface 
    end; 

    TXList<T: class> = class(TList<T>, IInterface, IXList<T>) 
    protected 
    FRefCount: Integer; 
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; 
    function _AddRef: Integer; stdcall; 
    function _Release: Integer; stdcall; 
    public 
    function Find: IXList<T>; 
    function FindAll<S: class>: IXList<S>; 
    end; 

implementation 
uses Windows; 

function TXList<T>.Find: IXList<T>; 
begin 
    Result := TXList<T>.Create; 
end; 

function TXList<T>.FindAll<S>: IXList<S>; 
begin 
    Result := IXList<S>(IUnknown(TXList<S>.Create)); 
end; 

function TXList<T>.QueryInterface(const IID: TGUID; out Obj): HResult; 
begin 
    Result := E_NoInterface; 
end; 

function TXList<T>._AddRef: Integer; 
begin 
    InterlockedIncrement(FRefCount); 
end; 

function TXList<T>._Release: Integer; 
begin 
    InterlockedDecrement(FRefCount); 
    if FRefCount = 0 then Self.Destroy; 
end; 

end. 
+0

Niza, el truco parecía ser la de nombrar explícitamente IInterface en la declaración de clase. Gracias. – PeterS

3

Eso definitivamente se ve como un error de compilación. Dicen que se han centrado mucho en mejorar los problemas genéricos para la próxima versión, Delphi XE. Cuando se publique, lo que debería ocurrir dentro de las próximas dos semanas, descargue la vista previa y vea si se compilará ahora. Si no, intente archivar un informe de error con QC.

Además, FindAll<S> probablemente debería declararse como function FindAll<S: class>: IXList<S>;. Eso no soluciona el error, pero un compilador que funcione probablemente te proporcione un error al respecto.

Cuestiones relacionadas