Delphi接口类型不兼容

AJ.*_*AJ. 1 delphi

我想做的就是向这两个具有相同间接祖先的类添加通用方法。

IMyMethods = interface
  procedure SomeMethod;
end;

TMyADODataset =class(TADODataset, IMyMethods) // ADO
public
  procedure SomeMethod;
end;

TMyUniDataset =class(TUniTable, IMyMethods) // UniDAC
public
  procedure SomeMethod;
end;
Run Code Online (Sandbox Code Playgroud)

SomeMethodADO 和 UniDAC 的实现方式不同。所以我认为界面是完美的。

然后我们有

TMyTable =class
private
  FDataset: TDataset;
end;
Run Code Online (Sandbox Code Playgroud)

这里我选择了 TDataset,因为它是 TADODataset 和 TUniTable 的共同祖先。

FDataset 可以实例化如下:

if FProvider = prADO then
  FDataset := TMyADODataset.Create
else
  FDataset := TMyUniDataset.Create;
Run Code Online (Sandbox Code Playgroud)

现在的问题是如何调用SomeMethodof FDataset,以下内容无法编译并给出类型不兼容错误:

IMyMethods(FDataset).SomeMethod;

这是因为TDataset没有实现IMyMethods,这是正确的。但是有什么办法可以欺骗编译器接受这个吗?或者有更好的解决方案吗?我想到了类助手,但 ADO 和 UniDAC 的实现SomeMethod会有所不同。

Rem*_*eau 6

使用函数从对象SysUtils.Supports()获取接口,eg:IMyMethodsFDataset

uses
  ..., SysUtils;

var
  Intf: IMyMethods;
...
if Supports(FDataset, IMyMethods, Intf) then
  Intf.SomeMethod;
Run Code Online (Sandbox Code Playgroud)

请注意,为了使其工作,IMyMethods需要为其分配一个 Guid,例如:

type
  IMyMethods = interface
    ['{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}']
    procedure SomeMethod;
  end;
Run Code Online (Sandbox Code Playgroud)

您可以通过按 直接在代码编辑器中生成新的 Guid Ctrl+Shift+G