Delphi 接口类型不兼容

Delphi interface type incompatibility

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

IMyMethods = interface
  procedure SomeMethod;
end;

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

TMyUniDataset =class(TUniTable, IMyMethods) // UniDAC
public
  procedure SomeMethod;
end;

SomeMethod 对 ADO 和 UniDAC 的实现方式不同。所以我认为一个界面是完美的。

然后我们有

TMyTable =class
private
  FDataset: TDataset;
end;

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

FDataset 可以实例化如下:

if FProvider = prADO then
  FDataset := TMyADODataset.Create
else
  FDataset := TMyUniDataset.Create;

现在的问题是如何调用FDatasetSomeMethod,下面编译不通过,报类型不兼容错误:

IMyMethods(FDataset).SomeMethod;

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

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

uses
  ..., SysUtils;

var
  Intf: IMyMethods;
...
if Supports(FDataset, IMyMethods, Intf) then
  Intf.SomeMethod;

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

type
  IMyMethods = interface
    ['{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}']
    procedure SomeMethod;
  end;

您可以直接在代码编辑器中生成新的 Guid,方法是按 Ctrl+Shift+G