开发者

Delphi: A generic list of generic-descendants and taking a generic as a parameter

I struggle a little with the understanding of generics and how they can and can not be used.

I have a generic class TControlMediator like this:

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;

I then make 'concret' subclasses for each control type that I want to mediate:

TEditMediator = class(TControlMediator<TEdit, string>)
public
  function GetValue: string; override;
  procedure SetValue(Value: string); override;
end;

So far, everything seems to work OK. Problems arise, though, when I want a list of TControlMediator descendants, or taking a TControlMediator 开发者_如何学编程as an parameter to a method:

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

The compiler stops with fatal errors:

[DCC Error] mediator.pas(23): E2003 Undeclared identifier: 'C'
[DCC Error] mediator.pas(28): E2007 Constant or type identifier expected

Do anybody have any clues on how this is supposed to be done?


Delphi has no covariance or contravariance on its generic types. Your generic types must use actual types as parameters. In other words, this:

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

...won't work because C and T are not generic type arguments to TViewMediator or actual types.

TControlMediator<TEdit, string> is a type. TList<TControlMEdiator<C, T>>, when there are no types C or T in scope is not a type. You can't use a generic type placeholder in an instantiation of a generic type unless those placeholders are in scope as generic arguments to the containing generic type or method.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜