简体   繁体   English

如何在Delphi中获取具有泛型类型的对象列表

[英]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.

相关问题 如何在Delphi 10.2中为通用接口创建列表? - How can I create a list for a generic interface in Delphi 10.2? 我可以在Delphi中具有对象类型过程的一般约束吗 - Can I have generic constrain of type procedure of object in Delphi 如何将对象转换为Delphi中泛型类型约束的接口 - How can I cast an object as an interface which is a generic type constraint in Delphi 如何测试未知的Delphi RTTI TValue是否反映了任何类型的通用TList <>(或至少TEnumerable <>)的对象? - How can I test if an unknown Delphi RTTI TValue reflects an object that is ANY type of generic TList<> (or at least TEnumerable<>)? Delphi:如何获取带有起始路径的正在运行的应用程序列表? - Delphi: how can i get list of running applications with starting path? 我可以在Delphi中创建特定接口的通用列表吗? - Can I create a generic list of a particular interface in Delphi? 如何在Delphi的泛型方法中完全限定类型标识符? - How do I fully qualify type identifiers in generic methods in Delphi? 如何在Delphi中将泛型类型转换为实际类型 - How to cast a generic type into an actual type in Delphi 如何在Delphi中将泛型转换为Variant - How can I convert from generic to Variant in Delphi 如何使用适用于 Delphi 的 Appercept AWS SDK 获取存储桶中的对象列表? - How to get list of objects in bucket, using Appercept AWS SDK for Delphi?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM