如何在 Delphi 中获取具有通用类型的对象列表
How can I get List of objects with Generic type in Delphi
我有几个类如下:
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;
如何获取具有从 TSystemBaseEntity 通过 Values 属性 继承的泛型类型的对象列表?
例如,发票列表 (TInvoiceHeaderEntity) 或请求列表 (TRequestHeaderEntity) 及其属性的访问权。
如果您想要一个包含 TSystemBaseEntity 的一个特定子 class 的 TDataList,请将 TDataList 定义为通用 class,并带有 type constraint
这定义为
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;
并用作
TInvoice = class(TDataList<TInvoiceHeaderEntity>)
public
procedure Execute; override;
end;
procedure TInvoice.Execute
var
InvoiceHeader: TInvoiceHeaderEntity;
begin
for InvoiceHeader in Values do
...
end;
如果您想要一种类型的 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;
你在这里可以做的是有一个过程,它接受一个新的后代类型列表,过滤值列表中适当类型的元素,并将它们添加到新列表中。
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;
我有几个类如下:
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;
如何获取具有从 TSystemBaseEntity 通过 Values 属性 继承的泛型类型的对象列表?
例如,发票列表 (TInvoiceHeaderEntity) 或请求列表 (TRequestHeaderEntity) 及其属性的访问权。
如果您想要一个包含 TSystemBaseEntity 的一个特定子 class 的 TDataList,请将 TDataList 定义为通用 class,并带有 type constraint
这定义为
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;
并用作
TInvoice = class(TDataList<TInvoiceHeaderEntity>)
public
procedure Execute; override;
end;
procedure TInvoice.Execute
var
InvoiceHeader: TInvoiceHeaderEntity;
begin
for InvoiceHeader in Values do
...
end;
如果您想要一种类型的 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;
你在这里可以做的是有一个过程,它接受一个新的后代类型列表,过滤值列表中适当类型的元素,并将它们添加到新列表中。
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;