通用方法返回Delphi 2010中的通用接口 [英] Generic method returning generic interface in Delphi 2010
问题描述
给出下面的代码,这是一个非常精细的实际代码版本,我得到以下错误:
$ b $ [DCC Error] Unit3.pas(31 ):E2010不兼容类型:'IXList< Unit3.TXList< T> .FindAll.S>'和'TXList< Unit3.TXList< T> .FindAll.S>'
<在FindAll< S>函数。
我不明白为什么,因为以前的函数没有问题。
任何人都可以点亮它吗?
是我还是它在编译器中的错误?
unit Unit3;
界面
使用Generics.Collections;
类型
IXList< T> = interface
end;
TXList< T:class> = class(TList< T> ;, IXList< T>)
保护
FRefCount:Integer;
函数QueryInterface(const IID:TGUID; out Obj):HResult; STDCALL;
函数_AddRef:Integer; STDCALL;
函数_Release:Integer; STDCALL;
public
function Find:IXList< T> ;;
函数FindAll< S>:IXList< S> ;;
end;
实现
使用Windows;
函数TXList< T> .Find:IXList< T>;
begin
Result:= TXList< T> ;.Create;
end;
函数TXList< T> .FindAll< S>:IXList< S>
begin
Result:= TXList< S> .Create; //错误在这里
end;
函数TXList< T> .QueryInterface(const IID:TGUID; out Obj):HResult;
begin
结果:= E_NoInterface;
end;
函数TXList< T> ._ AddRef:Integer;
begin
InterlockedIncrement(FRefCount);
end;
函数TXList< T> ._发布:整数;
begin
InterlockedDecrement(FRefCount);
如果FRefCount = 0,则Self.Destroy;
end;
结束。
感谢您的回答!
这看起来像一个编译器错误,有一个可接受的解决方法可用。
将接口声明为
IXList< T:class> = interface
函数GetEnumerator:TList< T> .TEnumerator;
end;
和findall实现为
function TXList< T> .FindAll< S>:IXList< S>
var
lst:TXList< S>;
我:T;
begin
lst:= TXList< S> .Create;
for i in Self do
if i.InheritsFrom(S)then lst.Add(S(TObject(i)));
结果:= IXList< S>(IUnknown(lst));
end;
我用一个简单的例子来解释它。
执行如下操作: var
l:TXList< TAClass>;
我:TASubclassOfTAClass;
开始
。
。
。
for i in l.FindAll< TASubclassOfTaclass>做
开始
//用
做一些事情end;
通过三个小修改(IInterface,FindAll withS :类[感谢梅森]和FindAll中的类型转换)我得到了它的编译。
完整代码:
unit Unit16;
界面
使用
Generics.Collections;
类型
IXList< T> = interface
end;
TXList< T:class> = class(TList< T> ;, IInterface,IXList< T>)
保护
FRefCount:Integer;
函数QueryInterface(const IID:TGUID; out Obj):HResult; STDCALL;
函数_AddRef:Integer; STDCALL;
函数_Release:Integer; STDCALL;
public
function Find:IXList< T> ;;
函数FindAll< S:class> ;: IXList< S>;
end;
实现
使用Windows;
函数TXList< T> .Find:IXList< T>;
begin
Result:= TXList< T> ;.Create;
end;
函数TXList< T> .FindAll< S> ;: IXList< S>
begin
Result:= IXList< S>(IUnknown(TXList< S> Create));
end;
函数TXList< T> .QueryInterface(const IID:TGUID; out Obj):HResult;
begin
结果:= E_NoInterface;
end;
函数TXList< T> ._ AddRef:Integer;
begin
InterlockedIncrement(FRefCount);
end;
函数TXList< T> ._发布:整数;
begin
InterlockedDecrement(FRefCount);
如果FRefCount = 0,则Self.Destroy;
end;
结束。
Given the code below, wich is a very trimmed down version of the actual code, I get the following error:
[DCC Error] Unit3.pas(31): E2010 Incompatible types: 'IXList<Unit3.TXList<T>.FindAll.S>' and 'TXList<Unit3.TXList<T>.FindAll.S>'
In the FindAll<S> function.
I can't really see why since there is no problem with the previous very similar function.
Can anyone shed some light on it?
Is it me or is it a bug in the compiler?
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.
Thanks for the answers! It seems like a compiler bug with an acceptable workaround available.
With the interface declared as
IXList<T: class> = interface
function GetEnumerator: TList<T>.TEnumerator;
end;
and findall implemented as
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;
I got it working in a simple example.
Doing something like:
var
l: TXList<TAClass>;
i: TASubclassOfTAClass;
begin
.
.
.
for i in l.FindAll<TASubclassOfTAClass> do
begin
// Do something with i
end;
With three minor modification (IInterface, FindAll with "S: class" [Thanks Mason] and the typecasts in FindAll) I got it compiling.
Full code:
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.
这篇关于通用方法返回Delphi 2010中的通用接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!