[英]How can I get List of objects with Generic type in Delphi
I have several classes as follows: 我有以下几种课程:
Type
TSystemBaseEntity = class(TPersistent)
private
FID: integer;
public
property ID: integer read FID write FID;
end;
TProcessHeaderEntity = class(TSystemBaseEntity)
private
FHeaderDate: TDateTime;
public
property HeaderDate: TDateTime read FHeaderDate write FHeaderDate;
end;
TInvoiceHeaderEntity = class(TProcessHeaderEntity)
private
FCustomerId: integer;
public
property CustomerId: integer read FCustomerId write FCustomerId;
end;
TRequestHeaderEntity = class(TProcessHeaderEntity)
private
FWarehouseId: integer;
public
property WarehouseId: integer read FWarehouseId write FWarehouseId;
end;
TDataList = class(TPersistent)
private
FValues: TObjectList<TSystemBaseEntity>;
protected
function SetCaption: string; virtual;
public
procedure Execute; virtual; abstract;
property Values: TObjectList<TSystemBaseEntity> read FValues;
end;
TInvoice = class(TDataList)
public
procedure Execute; override;
end;
How can I get list of objects with generic types that inherited from TSystemBaseEntity by Values property? 如何获取具有从Values属性从TSystemBaseEntity继承的泛型类型的对象的列表?
For example, a list of Invoices(TInvoiceHeaderEntity) or a list of Requests(TRequestHeaderEntity) and access to it's properties. 例如,发票清单(TInvoiceHeaderEntity)或请求清单(TRequestHeaderEntity),并可以访问其属性。
If you want a TDataList that holds one specific subclass of TSystemBaseEntity, define TDataList to be a generic class, with a type constraint 如果您希望一个TDataList包含一个TSystemBaseEntity的特定子类,则将TDataList定义为具有类型约束的通用类。
This is defined as 定义为
TDataList<T:TSystemBaseEntity> = class(TPersistent)
private
FValues: TObjectList<T>;
protected
function SetCaption: string; virtual;
public
procedure Execute; virtual; abstract;
property Values: TObjectList<T> read FValues;
end;
And used as 并用作
TInvoice = class(TDataList<TInvoiceHeaderEntity>)
public
procedure Execute; override;
end;
procedure TInvoice.Execute
var
InvoiceHeader: TInvoiceHeaderEntity;
begin
for InvoiceHeader in Values do
...
end;
If you instead want one type TDataList, with a member that is TObjectList<TSystemBaseEntity>
, you cannot use that as a TObjectList<TInvoiceHeaderEntity>
etc. Have a look at Wikipedia for an introduction, but also consider the following would be allowed under such a scheme: 如果改为使用一种类型为TDataList且成员为
TObjectList<TSystemBaseEntity>
,则不能将其用作TObjectList<TInvoiceHeaderEntity>
等。请查看Wikipedia的介绍,但也考虑到在这种情况下允许以下操作方案:
procedure DoBadThingsWithGenerics(aDataList: TDataList);
var
myInvoices: TObjectList<TInvoiceHeaderEntity>
myRequests: TObjectList<TRequestHeaderEntity>
Request: TRequestHeaderEntity;
begin
myInvoices := aDataList.Values<TInvoiceHeaderEntity>;
myRequests := aDataList.Values<TRequestHeaderEntity>;
// Some code ...
myInvoices.Add( TInvoiceHeaderEntity.Create );
// Some more code...
for Request in myRequests do
// Oops, we have a TInvoiceHeaderEntity pretending to be a TRequestHeaderEntity
end;
What you can do here is have a procedure that takes a new list of the decendant type, filtering elements of the Values list that are of the appropriate type and adding them to the new list. 您可以在这里执行一个过程,该过程获取新的子孙类型列表,过滤适当类型的“值”列表中的元素,并将其添加到新列表中。
procedure TDataList.FilterByType<S:TSystemBaseEntity> ( intoList: TObjectList<S> );
var
Value: TSystemBaseEntity;
begin
for Value in Values do
if Value is S then
intoList.Add( Value as S );
end;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.