【问题标题】:Process to convert TObjectlist to TObjectList<T> to use in TObjectDataset将 TObjectlist 转换为 TObjectList<T> 以在 TObjectDataset 中使用的过程
【发布时间】:2017-08-18 21:20:09
【问题描述】:

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

【问题讨论】:

  • 切换到使用库需要的类型,问题就消失了
  • 愿意,但数据来自仅支持系统的 orm 的 json。内容。 Tobjectlist 而不是泛型。因此上面的方法......似乎很接近
  • 也许可以找到一个更适合您的其余代码的 ORM 系统
  • 感谢尝试了一些,但总有一个权衡取舍。

标签: delphi dataset spring4d


【解决方案1】:

除了遍历对象并构建一个新的TObjectList&lt;T&gt; 来使其正常工作之外,还有其他方法吗?

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

【讨论】:

  • @TheBitman 这是对所提出问题的答案。有时答案是不可能的。
【解决方案2】:

你的问题有点错误。 Spring4d TObjectDataSet 采用IObjectList 接口,它是IList&lt;T&gt; 的特化,其中TTObject

此合约与Contnrs.TObjectList 匹配。所以“简单地”为你的TObjectList 创建一个实现IObjectList 的包装类。我只是用引号引起来,因为这个接口有很多方法。您可以使用TListBase&lt;T&gt; 作为已经实现所有方法的适配器的基类。然后你只需要覆盖一些(看看TList&lt;T&gt;是哪些)。

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

编辑:这是这样一个适配器类的完整代码:

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.

【讨论】:

  • 谢谢!非常感激。我添加了 fClassType := classType;到构造函数。
  • 是否有可能使实现强类型化而不是使用 TObject,本质上是一个基于泛型的适配器,如 TObjectListAdapte 仍然保留 TListBase 引入的功能。
  • 当然可以TObjectListAdaper&lt;T: class&gt; = class(TListBase&lt;T&gt;)。但是你需要使用as IObjectList,因为你不能直接实现它。
  • 感谢 Stefan 我按照建议实现了,但我想在“提供者”类中使用它,但收到错误 E2010 Incompatible types: 'TItem' and 'TObject' in XE2 code next 单元测试;接口使用 SysUtils、Classes、System.Contnrs、System.Generics.Defaults、System.Generics.Collections、ObjectListAdapter、Spring.Collections;类型 TItem = 类结束; TProvider = 类公共函数 Get: TPHSTObjectListAdapter;结尾;实现 { TClient } 函数 TProvider.Get: TPHSTObjectListAdapter;开始结束;结束。
  • 我认为我解决了它... TObjectListAdapter 的 GetItem 和 Extract 方法未转换为 T 因此与 TObject 相关的错误。已更改并开始工作:) 再次感谢 Stefan... 我很喜欢 spring4d 并且几乎没有触及表面:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 2013-02-06
  • 1970-01-01
相关资源
最近更新 更多