将 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>
的特化,其中 T
是 TObject
.
此合同与 Contnrs.TObjectList
匹配。所以 "simply" 为你的 TObjectList
创建一个包装器 class 来实现 IObjectList
。我只是用引号引起来,因为这个接口有很多方法。您可以使用 TListBase<T>
作为已实现所有方法的适配器的基础 class。然后你只需要覆盖一些(看看 TList<T>
那些是什么)。
需要知道的一个重要细节是 TObjectDataSet
需要知道列表中对象的确切 class。这是通过 IObjectList
的 ElementType
属性 完成的。如果 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.
我想使用依赖于 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>
的特化,其中 T
是 TObject
.
此合同与 Contnrs.TObjectList
匹配。所以 "simply" 为你的 TObjectList
创建一个包装器 class 来实现 IObjectList
。我只是用引号引起来,因为这个接口有很多方法。您可以使用 TListBase<T>
作为已实现所有方法的适配器的基础 class。然后你只需要覆盖一些(看看 TList<T>
那些是什么)。
需要知道的一个重要细节是 TObjectDataSet
需要知道列表中对象的确切 class。这是通过 IObjectList
的 ElementType
属性 完成的。如果 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.