Delphi:通用后代的通用列表,并将通用作为参数 [英] Delphi: A generic list of generic-descendants and taking a generic as a parameter
问题描述
我有一些泛型的理解,以及它们可以和不能使用的理解。
我有一个类通用类TControlMediator,如下所示:
TControlMediator< C,T> = class
private
FMediatedComponent:C;
public
构造函数Create(ComponentToMediate:C);
函数GetValue:T;虚拟;抽象;
程序SetValue(Value:T);虚拟;抽象;
属性MediatedControl:C读取FMediatedComponent;
结束
然后,我要为要调解的每个控件类型制作concret子类:
TEditMediator = class(TControlMediator< TEdit,string>)
public
function GetValue:string;覆盖
procedure SetValue(Value:string);覆盖
结束
到目前为止,一切似乎都可以正常工作。但是,当我想要一个TControlMediator后代列表,或者使用一个TControlMediator作为一个方法的参数时,出现问题:
TViewMediator = class
private
FControlMediators:TList< TControlMEdiator< C,T>
public
程序registerMediator(AControlMediator:TControlMediator< C,T>);
procedure unregisterMediator(AControlMediator:TControlMediator< C,T>);
结束
编译器停止致命错误:
<$ E2003未指定的标识符:'C'
[DCC错误] mediator.pas(28):E2007常量或类型标识符预计
有没有人有任何线索可以如何完成?
Delphi对其通用类型没有协方差或相反性。您的通用类型必须使用实际类型作为参数。换句话说,这是:
TViewMediator = class
private
FControlMediators:TList< TControlMEdiator< C, T>;
public
程序registerMediator(AControlMediator:TControlMediator< C,T>);
procedure unregisterMediator(AControlMediator:TControlMediator< C,T>);
结束
...不会工作,因为C和T不是通用类型参数 TViewMediator
或实际类型。
TControlMediator< TEdit,string>
类型。 TList< TControlMEdiator< C,T>
,当没有类型 C
或范围内的T
不是一种类型。您不能在通用类型的实例化中使用通用类型占位符,除非这些占位符作为包含泛型类型或方法的通用参数的范围。
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.
这篇关于Delphi:通用后代的通用列表,并将通用作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!