Delphi:通用后代的通用列表,并将通用作为参数 [英] Delphi: A generic list of generic-descendants and taking a generic as a parameter

查看:188
本文介绍了Delphi:通用后代的通用列表,并将通用作为参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些泛型的理解,以及它们可以和不能使用的理解。



我有一个类通用类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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆