2010-08-26 37 views
7

考慮下面的代碼,至極的是實際的代碼非常下調的版本,我得到以下錯誤:泛型方法在Delphi返回通用接口2010

[DCC錯誤] Unit3.pas(31):E2010不兼容的類型: 'IXList < Unit3.TXList <Ť> > .FindAll.S' 和 'TXList < Unit3.TXList <Ť> > .FindAll.S'

在的FindAll <小號>功能。

我真的不明白爲什麼,因爲與以前非常類似的功能沒有問題。

任何人都可以對此有所瞭解嗎?
是我還是它在編譯器中的錯誤?

unit 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. 

感謝您的回答! 這似乎是一個編譯器錯誤,並提供了可接受的解決方法。

隨着接口聲明爲

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

和的findAll實現

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; 

我得到了它在一個簡單的例子工作。

做這樣的事情:

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

回答

5

通過三個小修改(IInterface,FindAll與「S:class」[Thanks Mason]和FindAll中的類型轉換)我編譯了它。

全碼:

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

尼斯,關鍵似乎是在類聲明中明確命名IInterface。 謝謝。 – PeterS 2010-08-26 20:51:12

3

這肯定看起來像一個編譯器錯誤。他們說他們如何專注於改進下一個版本Delphi XE的泛型問題。當它發佈時,應該在接下來的幾周內下載預覽,看看現在是否會編譯。如果不是,請嘗試使用QC提交錯誤報告。

此外,FindAll<S>應該可能被宣佈爲function FindAll<S: class>: IXList<S>;。這並不能解決這個錯誤,但是一個工作編譯器可能會給你一個錯誤。