delphi - 使用通用接口(interface)的错误重载调用

标签 delphi delphi-xe2

假设我有这个定义:

TMyClass1 = class
end;

TMyClass2 = class
end;

IModel<T : class> = interface
  ['{E8262D6C-DCAB-46AC-822E-EC369CF734F8}']
  function List() : TObjectList<T>;
end;

IPresenter<T : class> = interface
  ['{98FB7751-D75A-4C51-B55A-0E5FE68BE213}']
  function Retrieve() : TObjectList<T>;
end;

IView<T : class> = interface
  ['{59384CD6-30D6-4BD8-AB3D-7FCF4D1A8618}']
  procedure AssignPresenter(APresenter : IPresenter<T>);
end;

TModel<T : class> = class(TInterfacedObject, IModel<T>)
public
  function List() : TObjectList<T>; virtual; abstract;
end;

TPresenter<T : class> = class(TInterfacedObject, IPresenter<T>)
strict private
  { Private declarations }
  FModel : IModel<T>;
  FView : IView<T>;
public
  constructor Create(AView : IView<T>);
  function Retrieve() : TObjectList<T>; virtual; abstract;
end;

TModelClass1 = class(TModel<TMyClass1>);

TPresenterClass1 = class(TPresenter<TMyClass1>);

TModelClass2 = class(TModel<TMyClass2>);

TPresenterClass2 = class(TPresenter<TMyClass2>);

我有这个表单来实现我定义的一些东西:

TForm1 = class(TForm, IView<TMyClass1>, IView<TMyClass2>)
  procedure FormCreate(Sender: TObject);
private
  { Private declarations }
  FPresenter1 : IPresenter<TMyClass1>;
  FPresenter2 : IPresenter<TMyClass2>;
  procedure AssignPresenter(APresenter : IPresenter<TMyClass1>); overload;
  procedure AssignPresenter(APresenter : IPresenter<TMyClass2>); overload;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 TPresenterClass1.Create((Self as IView<TMyClass1>));
 TPresenterClass2.Create((Self as IView<TMyClass2>));
end;

procedure TForm1.AssignPresenter(APresenter: IPresenter<TMyClass1>);
begin
  Self.FPresenter1 := APresenter;
end;

procedure TForm1.AssignPresenter(APresenter: IPresenter<TMyClass2>);
begin
  Self.FPresenter2 := APresenter;
end;

所以这里的问题是delphi无法弄清楚要调用什么方法,在这个例子中,只有AssignPresenter(APresenter: IPresenter<TMyClass2>)在这两种情况下都会被调用,所以我可能在这里遗漏了一些东西,但我无法弄清楚自动取款机。

提前致谢。

最佳答案

这可能是重复的,但我现在找不到它。

问题是as接口(interface)运算符与泛型不太兼容。 as运算符(operator)依赖于接口(interface) GUID。通过查询具有匹配 GUID 的接口(interface)来找到该接口(interface)。而且 GUID 根本不适合通用实例化。

现在让我们看看您的代码。

TPresenterClass1.Create((Self as IView<TMyClass1>));
TPresenterClass2.Create((Self as IView<TMyClass2>));

问题是 IView<TMyClass1>IView<TMyClass2>具有相同的 GUID:

type
  IView<T : class> = interface
    ['{59384CD6-30D6-4BD8-AB3D-7FCF4D1A8618}']
    procedure AssignPresenter(APresenter : IPresenter<T>);
  end;

所以都是IView<TMyClass1>IView<TMyClass2>共享相同的 GUID,并且当您使用 as 进行查询时,无论你是否请求 IView<TMyClass1> 都会返回相同的接口(interface)或IView<TMyClass2> .

所以,这里的底线是 as一旦对象实现了ISomeInterface<T>,通用接口(interface)就变得几乎毫无用处。两次不同的 T

Embarcadero 确实应该实现 as以支持泛型的方式。但我不会屏住你的呼吸。

您需要找到一种不同的方法来解决您的问题。

关于delphi - 使用通用接口(interface)的错误重载调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28462463/

相关文章:

delphi - Firemonkey相当于ActionList?

c++ - FStream 读取用 Delphi 的二进制编写器编写的二进制文件

delphi - 更改Delphi中单元的初始化顺序

delphi - 具有相同祖先的类的重复代码

ios - 火猴应用程序。需要数据更新

delphi - 按下 dbnavigator 删除按钮后,如何根据决策中止删除记录?

delphi - 我可以在 msbuild 命令行中添加条件定义吗?

delphi - 优化 TWebBrowser 的绘制以减少总 CPU 使用率

android - 套接字错误 110 : Connection Timed Out - Android Delphi SMTP Gmail

delphi-xe - 如何在 Pbear Html 查看器组件上显示电子邮件图像?