Reputation: 12898
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?
Upvotes: 3
Views: 1996
Reputation: 126547
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.
Upvotes: 7