Process to convert TObjectlist to TObjectList<T> to use in TObjectDataset

我的未来我决定 提交于 2019-12-11 06:08:42

问题


I would like to use TObjectDataset which relies on TObjectList<> (System.Generics.Collections / Spring.Collections) but only have a TObjectList (System.Contnrs). Is there any way besides for iterating through objects and building a new TObjectList<> to get this working? Ultimately I would like to couple the TObjectList to an Objectdataset in order to bind to an UI.


回答1:


Your question is slightly wrong. The Spring4d TObjectDataSet takes an IObjectList interface which is a specialization of IList<T> where T is TObject.

This contract is matched by the Contnrs.TObjectList. So "simply" create a wrapper class for your TObjectList that implements IObjectList. I put simply in quotes because this interface has quite a lot of methods. You can use TListBase<T> as base class for your adapter which already has all methods implemented. Then you only need to override a few (take a look at TList<T> which ones those are).

One important detail to know is that the TObjectDataSet needs to know the exact class of the objects in your list. This is done via the ElementType property of the IObjectList. If that returns TObject though this is not very helpful. So you need to override that method.

Edit: Here is the full code of such an adapter class:

unit Spring.Collections.ObjectListAdapter;

interface

uses
  Contnrs,
  TypInfo,
  Spring.Collections,
  Spring.Collections.Base;

type
  TObjectListAdapter = class(TListBase<TObject>, IObjectList)
  private
    fList: TObjectList;
    fClassType: TClass;
  protected
    function GetCapacity: Integer; override;
    function GetCount: Integer; override;
    function GetElementType: PTypeInfo; override;
    function GetItem(index: Integer): TObject; override;
    procedure SetCapacity(value: Integer); override;
    procedure SetItem(index: Integer; const value: TObject); override;
  public
    constructor Create(const list: TObjectList; classType: TClass);

    procedure Delete(index: Integer); override;
    function Extract(const item: TObject): TObject; override;
    procedure Insert(index: Integer; const item: TObject); override;

    procedure Exchange(index1, index2: Integer); override;
    procedure Move(currentIndex, newIndex: Integer); override;
  end;

implementation

uses
  Classes,
  Types;

{ TObjectListAdapter }

constructor TObjectListAdapter.Create(const list: TObjectList; classType: TClass);
begin
  inherited Create;
  fList := list;
  fClassType := classType;
end;

procedure TObjectListAdapter.Delete(index: Integer);
begin
  fList.Delete(index);
end;

procedure TObjectListAdapter.Exchange(index1, index2: Integer);
begin
  fList.Exchange(index1, index2);
end;

function TObjectListAdapter.Extract(const item: TObject): TObject;
begin
  Result := fList.Extract(item);
end;

function TObjectListAdapter.GetCapacity: Integer;
begin
  Result := fList.Capacity;
end;

function TObjectListAdapter.GetCount: Integer;
begin
  Result := fList.Count;
end;

function TObjectListAdapter.GetElementType: PTypeInfo;
begin
  Result := fClassType.ClassInfo;
end;

function TObjectListAdapter.GetItem(index: Integer): TObject;
begin
  Result := fList[index];
end;

procedure TObjectListAdapter.Insert(index: Integer; const item: TObject);
begin
  fList.Insert(index, item);
end;

procedure TObjectListAdapter.Move(currentIndex, newIndex: Integer);
begin
  fList.Move(currentIndex, newIndex);
end;

procedure TObjectListAdapter.SetCapacity(value: Integer);
begin
  fList.Capacity := value;
end;

procedure TObjectListAdapter.SetItem(index: Integer; const value: TObject);
begin
  fList[index] := value;
end;

end.



回答2:


Is there any way besides for iterating through objects and building a new TObjectList<T> to get this working?

There is not. The two types are not compatible.



来源:https://stackoverflow.com/questions/43024863/process-to-convert-tobjectlist-to-tobjectlistt-to-use-in-tobjectdataset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!