Delphi:一个泛型后代的通用列表和将泛型作为参数

3
我还有点困惑泛型的理解,以及它们可用和不可用的情况。
我有一个类TControlMediator,它是泛型的,像这样:
TControlMediator<C, T> = class
private
  FMediatedComponent: C;
public
  constructor Create(ComponentToMediate: C);

  function GetValue: T; virtual; abstract;
  procedure SetValue(Value: T); virtual; abstract;

  property MediatedControl: C read FMediatedComponent;
end;

然后我为每个我想要调解的控件类型创建“concret”子类:
TEditMediator = class(TControlMediator<TEdit, string>)
public
  function GetValue: string; override;
  procedure SetValue(Value: string); override;
end;

到目前为止,一切似乎都正常。但是,当我想要一个TControlMediator后代列表或将TControlMediator作为方法参数时,问题就会出现:
TViewMediator = class
private
  FControlMediators: TList<TControlMEdiator<C, T>>;
public
  procedure registerMediator(AControlMediator: TControlMediator<C, T>);
  procedure unregisterMediator(AControlMediator: TControlMediator<C, T>);
end;

编译器出现致命错误,停止运行:
[DCC Error] mediator.pas(23): E2003 Undeclared identifier: 'C'
[DCC Error] mediator.pas(28): E2007 Constant or type identifier expected

有人知道这应该如何完成吗?
1个回答

7

Delphi的泛型类型没有协变或逆变。您的泛型类型必须使用实际类型作为参数。换句话说,下面这个代码是不可行的:

TViewMediator = class
private
  FControlMediators: TList<TControlMEdiator<C, T>>;
public
  procedure registerMediator(AControlMediator: TControlMediator<C, T>);
  procedure unregisterMediator(AControlMediator: TControlMediator<C, T>);
end;

由于C和T不是TViewMediator的泛型类型参数或实际类型,因此此处无法使用。

TControlMediator<TEdit, string>是一种类型。当没有类型CT在作用域内时,TList<TControlMEdiator<C,T>>不是一种类型。除非这些占位符作为泛型参数出现在包含泛型类型或方法中,否则您不能在泛型类型的实例化中使用泛型类型占位符。


在我确切了解你为什么要这样做之前,我无法确定你是否遇到了问题。你能否将其参数化为 TViewMediator<C, T> - Craig Stuntz
我想注册不同类型的中介者,例如: MyViewMediator.RegisterMediator(TEditMediator.create(someEdit)); MyViewMediator.RegisterMediator(TComboMediator.create(someCombo));之后,我想循环所有已注册的中介者并调用它们的一个方法。 - Vegar
2
你可以给泛型类型一个非泛型的父类型,并将你的列表设置为该类型的列表。 - Craig Stuntz
嗯,但如果最好的父类是TList<T> 呢?那么这会让一切变得混乱。好的,我可以创建一个包装类TDummy,然后再创建几个子类TDummy<T:record> = class(TDummy) public Storage:TList<T>; end; 好吧,这看起来有点毫无意义,我仍然无法在TDummy集合上创建通用子程序... - Arioch 'The
我想要创建一个通用的磁盘扫描器,它具备多种引擎可以或不可以转换TFileName -> 一些记录,并且将它们存储到集合中,然后将这些集合保存到报告中。理想情况下,该引擎不应与后端存储耦合。所以我可以轻松地制作所有单独引擎并且对于它们生成的TList<T>。但是,我希望有一些分离的保存类/例程,可以得到结果集合并保存它们。理想情况下,应该有一个类似于TDictionary<>记录类型->引擎类的注册表。甚至最好有多个存储后端。 - Arioch 'The
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接