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;

然后,我为要调解的每种控件类型创建“具体”子类:

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

有没有人知道如何做到这一点?

4

1 回答 1

6

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>是一种类型。TList<TControlMEdiator<C, T>>,当没有类型CT范围内不是类型时。您不能在泛型类型的实例化中使用泛型类型占位符,除非这些占位符在范围内作为包含泛型类型或方法的泛型参数。

于 2009-10-27T18:53:16.710 回答