通用方法返回Delphi 2010中的通用接口 [英] Generic method returning generic interface in Delphi 2010

查看:134
本文介绍了通用方法返回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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆