7 Stimmen

Generische Methode, die generische Schnittstelle in Delphi 2010 zurückgibt

Bei dem unten stehenden Code, der eine stark gekürzte Version des tatsächlichen Codes ist, erhalte ich den folgenden Fehler:

[DCC Fehler] Unit3.pas(31): E2010 Inkompatible Typen: 'IXList.FindAll.S>' und 'TXList.FindAll.S>'

In der FindAll Funktion.

~~Ich kann den Grund dafür nicht wirklich sehen, da es kein Problem mit der vorherigen sehr ähnlichen Funktion gibt.

Kann jemand Licht ins Dunkel bringen?
Bin ich es oder ist es ein Bug im Compiler?

unit Unit3;

interface
uses Generics.Collections;

type
  IXList = interface
  end;

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

implementation
uses Windows;

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

function TXList.FindAll: IXList;
begin
  Result := TXList.Create; // Fehler tritt hier auf  
end;

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

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

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

end.


Mit der deklarierten Schnittstelle als

    IXList = interface
       function GetEnumerator: TList.TEnumerator;
    end;

und findall implementiert als

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

      Result := IXList(IUnknown(lst));
    end;

~~~~~~Habe ich es in einem einfachen Beispiel zum Laufen gebracht.

Etwas in der Art von:

    var
      l: TXList;
      i: TASubclassOfTAClass;
    begin
    .
    .
    .
    for i in l.FindAll do
    begin
       // Mache etwas mit i
    end;~~~~~~~~~~~~~~

5voto

Uwe Schuster Punkte 833

Mit drei kleinen Änderungen (IInterface, FindAll mit "S: class" [Danke Mason] und die Typprüfungen in FindAll) habe ich es kompilieren können.

Vollständiger Code:

unit Unit16;

interface

uses
  Generics.Collections;

type
  IXList = interface
  end;

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

implementation
uses Windows;

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

function TXList.FindAll: IXList;
begin
  Result := IXList(IUnknown(TXList.Create));
end;

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

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

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

end.

3voto

Mason Wheeler Punkte 79858

Dies sieht definitiv nach einem Compilerfehler aus. Sie sagen, dass sie sich sehr bemüht haben, die Generics-Probleme für die nächste Version, Delphi XE, zu verbessern. Wenn es veröffentlicht wird, was innerhalb der nächsten paar Wochen sein sollte, laden Sie die Vorschau herunter und prüfen Sie, ob es jetzt kompiliert. Wenn nicht, versuchen Sie, einen Fehlerbericht bei QC einzureichen.

Außerdem sollte FindAll wahrscheinlich als `function FindAll: IXList;` ~~deklariert werden. Das behebt nicht den Fehler, aber ein funktionierender Compiler würde Ihnen wahrscheinlich einen Fehler anzeigen.~~

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X