我有一些泛型的理解,以及它们可以和不能使用的理解。
我有一个类通用类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 expectedDo 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:通用后代的通用列表,并将通用作为参数
发布评论