Delphi接口通用功能 - 有没有解决方法?

Jas*_*son 10 delphi generics interface

我有以下代码

IProxy<T> = interface
  ['{1E3A98C5-78BA-4D65-A4BA-B6992B8B4783}']
  function Setup : ISetup<T>;
  function Proxy : T;
  function CastAs<I : IInterface> : IInterface;
end;
Run Code Online (Sandbox Code Playgroud)

有没有办法解决编译时收到的编译器错误?

"[DCC错误] Delphi.Mocks.pas(123):E2535接口方法必须没有参数化方法"

基本上我想通过传递类型转换为并返回该类型来传递此接口并能够抛弃它.我可以用一个类实现这个,但是更喜欢绕过一个接口.

附加信息:

说我有以下课程

TInterfaceProxy<T> = class(TBaseProxy<T>)
private type
  TProxyVirtualInterface = class(TVirtualInterface)
  private
    FProxy : TInterfaceProxy<T>;
  protected
  public
    function QueryInterface(const IID: TGUID; out Obj): HRESULT; override; stdcall;
    constructor Create(AProxy : TInterfaceProxy<T>; AInterface: Pointer; InvokeEvent: TVirtualInterfaceInvokeEvent);
  end;
private
  FVirtualInterfaces : TDictionary<TGUID, TProxyVirtualInterface>;
protected
  function InternalQueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall;
  function QueryInterface(const IID: TGUID; out Obj): HRESULT; override;
  function Proxy : T;override;
  function CastAs<I: IInterface> : I;
public
  constructor Create;override;
  destructor Destroy;override;
end;
Run Code Online (Sandbox Code Playgroud)

CastAs在这里运行良好,因为新请求的强制转换可以创建一个新的虚拟接口.现在,如果我想通过它的罚款.但是,如果我需要它作为一个接口,即TInterfaceProxy<T> = class(TBaseProxy<T>, IProxy<T>)它不能理解.不同意,但明白.

因此,我如何绕过这个限制,以便我可以调用CastAs函数,传入一个类型(任何接口类型开始),并能够从中创建一个虚拟接口?

Dav*_*nan 16

编译器说,接口不支持通用参数化方法.

没有解决方法,因为它是一个基本限制.类中的参数化方法是通过向每个实例添加一个方法来实现的.这适用于类,因为它们是具体的,但不适用于接口.这是因为接口是一个函数表,并且该表的大小不能根据代码中其他地方碰巧出现的泛型方法实例而变化.出于类似的原因,通用方法不能是虚拟的或动态的.

您的问题中的代码也有点误导.你写了:

function CastAs<I : IInterface> : IInterface;
Run Code Online (Sandbox Code Playgroud)

但我相信你的意思是:

function CastAs<I : IInterface> : I;
Run Code Online (Sandbox Code Playgroud)

无论如何,这是不可能的.一种选择是使用类来代替.我同意这是一个约束.

如果你想在界面中这样做,你可以做的最好的事情是:

function CastAs(const IID: TGUID): IInterface;
Run Code Online (Sandbox Code Playgroud)

但是你必须这样称呼它:

MyIntf := ProxyIntf.CastAs(IMyIntf) as IMyIntf;
Run Code Online (Sandbox Code Playgroud)

感觉有点犯规.

选择你的毒药!


Rem*_*eau 6

如错误消息所述,接口中的方法不能具有通用参数.编译器根本不支持它,并且记录如下:

http://docwiki.embarcadero.com/RADStudio/XE4/en/Overview_of_Generics

接口中的参数化方法

无法在接口中声明参数化方法(使用类型参数声明的方法).

换句话说,您的CastAs方法是非法的,因为它是在接口类型中声明的.另一方面,您首先不需要这样的方法.您可以使用SysUtils.Supports()将一个接口转换为另一个接口.