将 TObjectlist 转换为 TObjectList<T> 以在 TObjectDataset 中使用的过程

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

我想使用依赖于 TObjectList<> (System.Generics.Collections / Spring.Collections) 但只有一个 TObjectList (System.Contnrs) 的 TObjectDataset。除了遍历对象和构建新的 TObjectList<> 之外还有什么方法可以使它正常工作吗?最终我想将 TObjectList 耦合到 Objectdataset 以便绑定到 UI.

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

没有。这两种类型不兼容。

你的问题有点错误。 Spring4d TObjectDataSet 采用 IObjectList 接口,它是 IList<T> 的特化,其中 TTObject.

此合同与 Contnrs.TObjectList 匹配。所以 "simply" 为你的 TObjectList 创建一个包装器 class 来实现 IObjectList。我只是用引号引起来,因为这个接口有很多方法。您可以使用 TListBase<T> 作为已实现所有方法的适配器的基础 class。然后你只需要覆盖一些(看看 TList<T> 那些是什么)。

需要知道的一个重要细节是 TObjectDataSet 需要知道列表中对象的确切 class。这是通过 IObjectListElementType 属性 完成的。如果 returns TObject 虽然这不是很有帮助。所以你需要覆盖那个方法。

编辑:这是此类适配器的完整代码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.